// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// Original code is licensed as follows:
/*
 * Copyright 2013 ZXing authors
 *
 * 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 <limits>

#include "xfa/src/fxbarcode/pdf417/BC_PDF417CodewordDecoder.h"
#include "xfa/src/fxbarcode/pdf417/BC_PDF417Common.h"

#define SYMBOL_TABLE_Length 2787

FX_FLOAT CBC_PDF417CodewordDecoder::RATIOS_TABLE[2787][8] = {{0}};

CBC_PDF417CodewordDecoder::CBC_PDF417CodewordDecoder() {}
CBC_PDF417CodewordDecoder::~CBC_PDF417CodewordDecoder() {}
void CBC_PDF417CodewordDecoder::Initialize() {
  for (int32_t i = 0; i < SYMBOL_TABLE_Length; i++) {
    int32_t currentSymbol = CBC_PDF417Common::SYMBOL_TABLE[i];
    int32_t currentBit = currentSymbol & 0x1;
    for (int32_t j = 0; j < CBC_PDF417Common::BARS_IN_MODULE; j++) {
      FX_FLOAT size = 0.0f;
      while ((currentSymbol & 0x1) == currentBit) {
        size += 1.0f;
        currentSymbol >>= 1;
      }
      currentBit = currentSymbol & 0x1;
      RATIOS_TABLE[i][CBC_PDF417Common::BARS_IN_MODULE - j - 1] =
          size / CBC_PDF417Common::MODULES_IN_CODEWORD;
    }
  }
}
void CBC_PDF417CodewordDecoder::Finalize() {}
int32_t CBC_PDF417CodewordDecoder::getDecodedValue(
    CFX_Int32Array& moduleBitCount) {
  CFX_Int32Array* array = sampleBitCounts(moduleBitCount);
  int32_t decodedValue = getDecodedCodewordValue(*array);
  delete array;
  if (decodedValue != -1) {
    return decodedValue;
  }
  return getClosestDecodedValue(moduleBitCount);
}
CFX_Int32Array* CBC_PDF417CodewordDecoder::sampleBitCounts(
    CFX_Int32Array& moduleBitCount) {
  FX_FLOAT bitCountSum =
      (FX_FLOAT)CBC_PDF417Common::getBitCountSum(moduleBitCount);
  CFX_Int32Array* bitCount = new CFX_Int32Array();
  bitCount->SetSize(CBC_PDF417Common::BARS_IN_MODULE);
  int32_t bitCountIndex = 0;
  int32_t sumPreviousBits = 0;
  for (int32_t i = 0; i < CBC_PDF417Common::MODULES_IN_CODEWORD; i++) {
    FX_FLOAT sampleIndex =
        bitCountSum / (2 * CBC_PDF417Common::MODULES_IN_CODEWORD) +
        (i * bitCountSum) / CBC_PDF417Common::MODULES_IN_CODEWORD;
    if (sumPreviousBits + moduleBitCount.GetAt(bitCountIndex) <= sampleIndex) {
      sumPreviousBits += moduleBitCount.GetAt(bitCountIndex);
      bitCountIndex++;
    }
    bitCount->SetAt(bitCountIndex, bitCount->GetAt(bitCountIndex) + 1);
  }
  return bitCount;
}
int32_t CBC_PDF417CodewordDecoder::getDecodedCodewordValue(
    CFX_Int32Array& moduleBitCount) {
  int32_t decodedValue = getBitValue(moduleBitCount);
  return CBC_PDF417Common::getCodeword(decodedValue) == -1 ? -1 : decodedValue;
}
int32_t CBC_PDF417CodewordDecoder::getBitValue(CFX_Int32Array& moduleBitCount) {
  int64_t result = 0;
  for (int32_t i = 0; i < moduleBitCount.GetSize(); i++) {
    for (int32_t bit = 0; bit < moduleBitCount.GetAt(i); bit++) {
      result = (result << 1) | (i % 2 == 0 ? 1 : 0);
    }
  }
  return (int32_t)result;
}
int32_t CBC_PDF417CodewordDecoder::getClosestDecodedValue(
    CFX_Int32Array& moduleBitCount) {
  int32_t bitCountSum = CBC_PDF417Common::getBitCountSum(moduleBitCount);
  CFX_FloatArray bitCountRatios;
  bitCountRatios.SetSize(CBC_PDF417Common::BARS_IN_MODULE);
  for (int32_t i = 0; i < bitCountRatios.GetSize(); i++) {
    bitCountRatios[i] = moduleBitCount.GetAt(i) / (FX_FLOAT)bitCountSum;
  }
  FX_FLOAT bestMatchError = std::numeric_limits<int32_t>::max();
  int32_t bestMatch = -1;
  for (int32_t j = 0; j < SYMBOL_TABLE_Length; j++) {
    FX_FLOAT error = 0.0f;
    for (int32_t k = 0; k < CBC_PDF417Common::BARS_IN_MODULE; k++) {
      FX_FLOAT diff = RATIOS_TABLE[j][k] - bitCountRatios[k];
      error += diff * diff;
    }
    if (error < bestMatchError) {
      bestMatchError = error;
      bestMatch = CBC_PDF417Common::SYMBOL_TABLE[j];
    }
  }
  return bestMatch;
}
