1d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Copyright 2014 PDFium Authors. All rights reserved.
2d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Use of this source code is governed by a BSD-style license that can be
3d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// found in the LICENSE file.
4d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
5d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann// Original code is licensed as follows:
7d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann/*
8d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * Copyright 2007 ZXing authors
9d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *
10d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * Licensed under the Apache License, Version 2.0 (the "License");
11d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * you may not use this file except in compliance with the License.
12d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * You may obtain a copy of the License at
13d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *
14d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *      http://www.apache.org/licenses/LICENSE-2.0
15d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann *
16d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * Unless required by applicable law or agreed to in writing, software
17d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * distributed under the License is distributed on an "AS IS" BASIS,
18d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * See the License for the specific language governing permissions and
20d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann * limitations under the License.
21d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann */
22d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
23d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/common/reedsolomon/BC_ReedSolomonGF256Poly.h"
24d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
25d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <memory>
26d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include <utility>
27d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
28d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "fxbarcode/common/reedsolomon/BC_ReedSolomonGF256.h"
29d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/ptr_util.h"
30d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann#include "third_party/base/stl_util.h"
31d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
32d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly(CBC_ReedSolomonGF256* field,
33d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                                   int32_t coefficients) {
34d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!field)
35d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return;
36d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
37d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_field = field;
38d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_coefficients.push_back(coefficients);
39d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
40d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
41d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCBC_ReedSolomonGF256Poly::CBC_ReedSolomonGF256Poly() {
42d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_field = nullptr;
43d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
44d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
45d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CBC_ReedSolomonGF256Poly::Init(CBC_ReedSolomonGF256* field,
46d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                    const std::vector<int32_t>* coefficients) {
47d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!coefficients || coefficients->empty())
48d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return false;
49d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
50d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  m_field = field;
51d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t coefficientsLength = coefficients->size();
52d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (coefficientsLength > 1 && coefficients->front() == 0) {
53d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    size_t firstNonZero = 1;
54d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    while (firstNonZero < coefficientsLength &&
55d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann           (*coefficients)[firstNonZero] == 0) {
56d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      firstNonZero++;
57d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
58d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (firstNonZero == coefficientsLength) {
59d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_coefficients = m_field->GetZero()->GetCoefficients();
60d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    } else {
61d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_coefficients.resize(coefficientsLength - firstNonZero);
62d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      for (size_t i = firstNonZero, j = 0; i < coefficientsLength; i++, j++)
63d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        m_coefficients[j] = (*coefficients)[i];
64d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
65d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  } else {
66d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    m_coefficients = *coefficients;
67d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
68d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return true;
69d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
70d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
71d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannconst std::vector<int32_t>& CBC_ReedSolomonGF256Poly::GetCoefficients() const {
72d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_coefficients;
73d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
74d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
75d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint32_t CBC_ReedSolomonGF256Poly::GetDegree() const {
76d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return pdfium::CollectionSize<int32_t>(m_coefficients) - 1;
77d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
78d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
79d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannbool CBC_ReedSolomonGF256Poly::IsZero() const {
80d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_coefficients.front() == 0;
81d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
82d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
83d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint32_t CBC_ReedSolomonGF256Poly::GetCoefficients(int32_t degree) const {
84d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return m_coefficients[m_coefficients.size() - 1 - degree];
85d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
86d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
87d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannint32_t CBC_ReedSolomonGF256Poly::EvaluateAt(int32_t a) {
88d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (a == 0)
89d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return GetCoefficients(0);
90d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
91d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t size = m_coefficients.size();
92d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (a == 1) {
93d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t result = 0;
94d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    for (size_t i = 0; i < size; i++)
95d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      result = CBC_ReedSolomonGF256::AddOrSubtract(result, m_coefficients[i]);
96d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return result;
97d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
98d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t result = m_coefficients[0];
99d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t j = 1; j < size; j++) {
100d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    result = CBC_ReedSolomonGF256::AddOrSubtract(m_field->Multiply(a, result),
101d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                                 m_coefficients[j]);
102d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
103d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return result;
104d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
105d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
106d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly> CBC_ReedSolomonGF256Poly::Clone()
107d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const {
108d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto temp = pdfium::MakeUnique<CBC_ReedSolomonGF256Poly>();
109d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!temp->Init(m_field.Get(), &m_coefficients))
110d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
111d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return temp;
112d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
113d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
114d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly>
115d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCBC_ReedSolomonGF256Poly::AddOrSubtract(const CBC_ReedSolomonGF256Poly* other) {
116d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (IsZero())
117d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return other->Clone();
118d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (other->IsZero())
119d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Clone();
120d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
121d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> smallerCoefficients = m_coefficients;
122d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> largerCoefficients = other->GetCoefficients();
123d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (smallerCoefficients.size() > largerCoefficients.size())
124d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    std::swap(smallerCoefficients, largerCoefficients);
125d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
126d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> sumDiff(largerCoefficients.size());
127d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t lengthDiff = largerCoefficients.size() - smallerCoefficients.size();
128d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < lengthDiff; i++)
129d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    sumDiff[i] = largerCoefficients[i];
130d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
131d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t j = lengthDiff; j < largerCoefficients.size(); j++) {
132d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    sumDiff[j] = CBC_ReedSolomonGF256::AddOrSubtract(
133d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        smallerCoefficients[j - lengthDiff], largerCoefficients[j]);
134d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
135d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto temp = pdfium::MakeUnique<CBC_ReedSolomonGF256Poly>();
136d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!temp->Init(m_field.Get(), &sumDiff))
137d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
138d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return temp;
139d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
140d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
141d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly> CBC_ReedSolomonGF256Poly::Multiply(
142d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const CBC_ReedSolomonGF256Poly* other) {
143d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (IsZero() || other->IsZero())
144d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_field->GetZero()->Clone();
145d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
146d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const std::vector<int32_t>& aCoefficients = m_coefficients;
147d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  const std::vector<int32_t>& bCoefficients = other->GetCoefficients();
148d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t aLength = aCoefficients.size();
149d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t bLength = bCoefficients.size();
150d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> product(aLength + bLength - 1);
151d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < aLength; i++) {
152d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t aCoeff = aCoefficients[i];
153d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    for (size_t j = 0; j < bLength; j++) {
154d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      product[i + j] = CBC_ReedSolomonGF256::AddOrSubtract(
155d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann          product[i + j], m_field->Multiply(aCoeff, bCoefficients[j]));
156d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    }
157d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
158d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto temp = pdfium::MakeUnique<CBC_ReedSolomonGF256Poly>();
159d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!temp->Init(m_field.Get(), &product))
160d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
161d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return temp;
162d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
163d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
164d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly> CBC_ReedSolomonGF256Poly::Multiply(
165d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t scalar) {
166d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (scalar == 0)
167d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_field->GetZero()->Clone();
168d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (scalar == 1)
169d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return Clone();
170d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
171d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t size = m_coefficients.size();
172d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> product(size);
173d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < size; i++)
174d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    product[i] = m_field->Multiply(m_coefficients[i], scalar);
175d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
176d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto temp = pdfium::MakeUnique<CBC_ReedSolomonGF256Poly>();
177d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!temp->Init(m_field.Get(), &product))
178d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
179d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return temp;
180d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
181d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
182d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly>
183d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCBC_ReedSolomonGF256Poly::MultiplyByMonomial(int32_t degree,
184d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                                             int32_t coefficient) const {
185d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (degree < 0)
186d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
187d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (coefficient == 0)
188d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return m_field->GetZero()->Clone();
189d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
190d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  size_t size = m_coefficients.size();
191d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  std::vector<int32_t> product(size + degree);
192d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  for (size_t i = 0; i < size; i++)
193d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    product[i] = m_field->Multiply(m_coefficients[i], coefficient);
194d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
195d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto temp = pdfium::MakeUnique<CBC_ReedSolomonGF256Poly>();
196d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!temp->Init(m_field.Get(), &product))
197d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
198d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return temp;
199d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
200d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
201d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmannstd::unique_ptr<CBC_ReedSolomonGF256Poly> CBC_ReedSolomonGF256Poly::Divide(
202d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    const CBC_ReedSolomonGF256Poly* other) {
203d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (other->IsZero())
204d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
205d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
206d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto quotient = m_field->GetZero()->Clone();
207d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!quotient)
208d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
209d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  auto remainder = Clone();
210d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (!remainder)
211d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
212d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
213d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int e = BCExceptionNO;
214d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t denominatorLeadingTerm = other->GetCoefficients(other->GetDegree());
215d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  int32_t inverseDenominatorLeadingTeam =
216d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      m_field->Inverse(denominatorLeadingTerm, e);
217d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  if (e != BCExceptionNO)
218d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    return nullptr;
219d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  while (remainder->GetDegree() >= other->GetDegree() && !remainder->IsZero()) {
220d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t degreeDifference = remainder->GetDegree() - other->GetDegree();
221d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    int32_t scale =
222d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann        m_field->Multiply(remainder->GetCoefficients((remainder->GetDegree())),
223d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann                          inverseDenominatorLeadingTeam);
224d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    auto term = other->MultiplyByMonomial(degreeDifference, scale);
225d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!term)
226d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return nullptr;
227d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    auto iteratorQuotient = m_field->BuildMonomial(degreeDifference, scale, e);
228d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (e != BCExceptionNO)
229d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return nullptr;
230d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    quotient = quotient->AddOrSubtract(iteratorQuotient.get());
231d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!quotient)
232d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return nullptr;
233d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    remainder = remainder->AddOrSubtract(term.get());
234d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann    if (!remainder)
235d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann      return nullptr;
236d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  }
237d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann  return remainder;
238d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann}
239d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. Moltmann
240d904c1ec7e8d1d86ed56f0dd252435d12cd345aePhilip P. MoltmannCBC_ReedSolomonGF256Poly::~CBC_ReedSolomonGF256Poly() {}
241