Many changes to the C++ port.
[zxing.git] / cpp / core / src / common / reedsolomon / ReedSolomonDecoder.cpp
diff --git a/cpp/core/src/common/reedsolomon/ReedSolomonDecoder.cpp b/cpp/core/src/common/reedsolomon/ReedSolomonDecoder.cpp
deleted file mode 100644 (file)
index 7fcc8ff..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  ReedSolomonDecoder.cpp
- *  zxing
- *
- *  Created by Christian Brunschen on 05/05/2008.
- *  Copyright 2008 Google UK. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <iostream>
-
-#include <memory>
-#include "ReedSolomonDecoder.h"
-#include "GF256.h"
-#include "GF256Poly.h"
-#include "ReedSolomonException.h"
-
-using namespace std;
-
-namespace reedsolomon {
-  ReedSolomonDecoder::ReedSolomonDecoder(GF256 &fld) : field(fld) {
-  }
-  
-  ReedSolomonDecoder::~ReedSolomonDecoder() {
-  }
-  
-  void ReedSolomonDecoder::decode(ArrayRef<int> received, int twoS) {
-    
-    Ref<GF256Poly> poly(new GF256Poly(field, received));
-    
-#ifdef DEBUG
-    cout << "decoding with poly " << *poly << "\n";
-#endif
-    
-    ArrayRef<int> syndromeCoefficients(new Array<int>(twoS));
-    
-#ifdef DEBUG
-    cout << "syndromeCoefficients array = " << 
-      syndromeCoefficients.array_ << "\n";
-#endif
-    
-    bool noError = true;
-    for (int i = 0; i < twoS; i++) {
-      int eval = poly->evaluateAt(field.exp(i));
-      syndromeCoefficients[syndromeCoefficients->size() - 1 - i] = eval;
-      if (eval != 0) {
-        noError = false;
-      }
-    }
-    if (noError) {
-      return;
-    }
-
-    Ref<GF256Poly> syndrome(new GF256Poly(field, syndromeCoefficients));
-    Ref<GF256Poly> monomial(field.buildMonomial(twoS, 1));
-    vector<Ref<GF256Poly> > sigmaOmega
-      (runEuclideanAlgorithm(monomial, syndrome, twoS));
-    ArrayRef<int> errorLocations = findErrorLocations(sigmaOmega[0]);
-    ArrayRef<int> errorMagitudes = findErrorMagnitudes(sigmaOmega[1],
-                                                       errorLocations);
-    for (unsigned i = 0; i < errorLocations->size(); i++) {
-      int position = received->size() - 1 - field.log(errorLocations[i]);
-      received[position] = GF256::addOrSubtract(received[position],
-                                                errorMagitudes[i]);
-    }
-  }
-  
-  vector<Ref<GF256Poly> > ReedSolomonDecoder::
-  runEuclideanAlgorithm(Ref<GF256Poly> a,
-                        Ref<GF256Poly> b,
-                        int R) {
-    // Assume a's degree is >= b's
-    if (a->getDegree() < b->getDegree()) {
-      Ref<GF256Poly> tmp = a;
-      a = b;
-      b = tmp;
-    }
-    
-    Ref<GF256Poly> rLast(a);
-    Ref<GF256Poly> r(b);
-    Ref<GF256Poly> sLast(field.getOne());
-    Ref<GF256Poly> s(field.getZero());
-    Ref<GF256Poly> tLast(field.getZero());
-    Ref<GF256Poly> t(field.getOne());
-    
-    // Run Euclidean algorithm until r's degree is less than R/2
-    while (r->getDegree() >= R / 2) {
-      Ref<GF256Poly> rLastLast(rLast);
-      Ref<GF256Poly> sLastLast(sLast);
-      Ref<GF256Poly> tLastLast(tLast);
-      rLast = r;
-      sLast = s;
-      tLast = t;
-      
-      // Divide rLastLast by rLast, with quotient q and remainder r
-      if (rLast->isZero()) {
-        // Oops, Euclidean algorithm already terminated?
-        throw ReedSolomonException("r_{i-1} was zero");
-      }
-      r = rLastLast;
-      Ref<GF256Poly> q(field.getZero());
-      int denominatorLeadingTerm = rLast->getCoefficient(rLast->getDegree());
-      int dltInverse = field.inverse(denominatorLeadingTerm);
-      while (r->getDegree() >= rLast->getDegree() && !r->isZero()) {
-        int degreeDiff = r->getDegree() - rLast->getDegree();
-        int scale = field.multiply(r->getCoefficient(r->getDegree()), 
-                                   dltInverse);
-        q = q->addOrSubtract(field.buildMonomial(degreeDiff, scale));
-        r = r->addOrSubtract(rLast->multiplyByMonomial(degreeDiff, scale));
-      }
-      
-      s = q->multiply(sLast)->addOrSubtract(sLastLast);
-      t = q->multiply(tLast)->addOrSubtract(tLastLast);
-    }
-    
-    int sigmaTildeAtZero = t->getCoefficient(0);
-    if (sigmaTildeAtZero == 0) {
-      throw ReedSolomonException("sigmaTilde(0) was zero");
-    }
-    
-    int inverse = field.inverse(sigmaTildeAtZero);
-    Ref<GF256Poly> sigma(t->multiply(inverse));
-    Ref<GF256Poly> omega(r->multiply(inverse));
-    
-#ifdef DEBUG
-    cout << "t = " << *t << "\n";
-    cout << "r = " << *r << "\n";
-    cout << "sigma = " << *sigma << "\n";
-    cout << "omega = " << *omega << "\n";
-#endif
-    
-    vector<Ref<GF256Poly> > result(2);
-    result[0] = sigma;
-    result[1] = omega;
-    return result;
-  }
-  
-  ArrayRef<int> ReedSolomonDecoder::
-  findErrorLocations(Ref<GF256Poly> errorLocator) {
-    // This is a direct application of Chien's search
-    int numErrors = errorLocator->getDegree();
-    if (numErrors == 1) { // shortcut
-      ArrayRef<int> result(1);
-      result[0] = errorLocator->getCoefficient(1);
-      return result;
-    }
-    ArrayRef<int> result(numErrors);
-    int e = 0;
-    for (int i = 1; i < 256 && e < numErrors; i++) {
-      // cout << "errorLocator(" << i << ") == " << errorLocator->evaluateAt(i) << "\n";
-      if (errorLocator->evaluateAt(i) == 0) {
-        result[e] = field.inverse(i);
-        e++;
-      }
-    }
-    if (e != numErrors) {
-      throw ReedSolomonException
-        ("Error locator degree does not match number of roots");
-    }
-    return result;
-  }
-  
-  ArrayRef<int> ReedSolomonDecoder::
-  findErrorMagnitudes(Ref<GF256Poly> errorEvaluator,
-                      ArrayRef<int> errorLocations) {
-    // This is directly applying Forney's Formula
-    int s = errorLocations.size();
-    ArrayRef<int> result(s);
-    for (int i = 0; i < s; i++) {
-      int xiInverse = field.inverse(errorLocations[i]);
-      int denominator = 1;
-      for (int j = 0; j < s; j++) {
-        if (i != j) {
-          denominator = 
-            field.multiply(denominator,
-                           GF256::addOrSubtract
-                            (1, field.multiply(errorLocations[j], xiInverse)));
-        }
-      }
-      result[i] = field.multiply(errorEvaluator->evaluateAt(xiInverse),
-                                 field.inverse(denominator));
-    }
-    return result;
-  }
-}