// 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 2009 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 "xfa/fxbarcode/common/BC_GlobalHistogramBinarizer.h"

#include <memory>

#include "xfa/fxbarcode/BC_Binarizer.h"
#include "xfa/fxbarcode/BC_LuminanceSource.h"
#include "xfa/fxbarcode/common/BC_CommonBitArray.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/utils.h"

const int32_t LUMINANCE_BITS = 5;
const int32_t LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
const int32_t LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;

CBC_GlobalHistogramBinarizer::CBC_GlobalHistogramBinarizer(
    CBC_LuminanceSource* source)
    : CBC_Binarizer(source) {}
CBC_GlobalHistogramBinarizer::~CBC_GlobalHistogramBinarizer() {}
CBC_CommonBitArray* CBC_GlobalHistogramBinarizer::GetBlackRow(
    int32_t y,
    CBC_CommonBitArray* row,
    int32_t& e) {
  CBC_LuminanceSource* source = GetLuminanceSource();
  int32_t width = source->GetWidth();
  std::unique_ptr<CBC_CommonBitArray> result(new CBC_CommonBitArray(width));
  InitArrays(width);
  CFX_ByteArray* localLuminances = source->GetRow(y, m_luminance, e);
  if (e != BCExceptionNO) {
    return result.release();
  }
  CFX_Int32Array localBuckets;
  localBuckets.Copy(m_buckets);
  int32_t x;
  for (x = 0; x < width; x++) {
    int32_t pixel = (*localLuminances)[x] & 0xff;
    localBuckets[pixel >> LUMINANCE_SHIFT]++;
  }
  int32_t blackPoint = EstimateBlackPoint(localBuckets, e);
  if (e != BCExceptionNO) {
    return result.release();
  }
  int32_t left = (*localLuminances)[0] & 0xff;
  int32_t center = (*localLuminances)[1] & 0xff;
  for (x = 1; x < width - 1; x++) {
    int32_t right = (*localLuminances)[x + 1] & 0xff;
    int32_t luminance = ((center << 2) - left - right) >> 1;
    if (luminance < blackPoint) {
      result->Set(x);
    }
    left = center;
    center = right;
  }
  return result.release();
}
CBC_CommonBitMatrix* CBC_GlobalHistogramBinarizer::GetBlackMatrix(int32_t& e) {
  CBC_LuminanceSource* source = GetLuminanceSource();
  int32_t width = source->GetWidth();
  int32_t height = source->GetHeight();
  std::unique_ptr<CBC_CommonBitMatrix> matrix(new CBC_CommonBitMatrix());
  matrix->Init(width, height);
  InitArrays(width);
  CFX_Int32Array localBuckets;
  localBuckets.Copy(m_buckets);
  int32_t y;
  for (y = 1; y < 5; y++) {
    int32_t row = height * y / 5;
    CFX_ByteArray* localLuminances = source->GetRow(row, m_luminance, e);
    BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
    int32_t right = (width << 2) / 5;
    int32_t x;
    for (x = width / 5; x < right; x++) {
      int32_t pixel = (*localLuminances)[x] & 0xff;
      localBuckets[pixel >> LUMINANCE_SHIFT]++;
    }
  }
  int32_t blackPoint = EstimateBlackPoint(localBuckets, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  std::unique_ptr<CFX_ByteArray> localLuminances(source->GetMatrix());
  for (y = 0; y < height; y++) {
    int32_t offset = y * width;
    for (int32_t x = 0; x < width; x++) {
      int32_t pixel = (*localLuminances)[offset + x] & 0xff;
      if (pixel < blackPoint) {
        matrix->Set(x, y);
      }
    }
  }
  return matrix.release();
}
void CBC_GlobalHistogramBinarizer::InitArrays(int32_t luminanceSize) {
  if (m_luminance.GetSize() < luminanceSize) {
    m_luminance.SetSize(luminanceSize);
  }
  if (m_buckets.GetSize() <= 0) {
    m_buckets.SetSize(LUMINANCE_BUCKETS);
  } else {
    int32_t x;
    for (x = 0; x < LUMINANCE_BUCKETS; x++) {
      m_buckets[x] = 0;
    }
  }
}
int32_t CBC_GlobalHistogramBinarizer::EstimateBlackPoint(
    CFX_Int32Array& buckets,
    int32_t& e) {
  int32_t numBuckets = buckets.GetSize();
  int32_t maxBucketCount = 0;
  int32_t firstPeak = 0;
  int32_t firstPeakSize = 0;
  int32_t x;
  for (x = 0; x < numBuckets; x++) {
    if (buckets[x] > firstPeakSize) {
      firstPeak = x;
      firstPeakSize = buckets[x];
    }
    if (buckets[x] > maxBucketCount) {
      maxBucketCount = buckets[x];
    }
  }
  int32_t secondPeak = 0;
  int32_t secondPeakScore = 0;
  for (x = 0; x < numBuckets; x++) {
    int32_t distanceToBiggest = x - firstPeak;
    int32_t score = buckets[x] * distanceToBiggest * distanceToBiggest;
    if (score > secondPeakScore) {
      secondPeak = x;
      secondPeakScore = score;
    }
  }
  if (firstPeak > secondPeak) {
    int32_t temp = firstPeak;
    firstPeak = secondPeak;
    secondPeak = temp;
  }
  if (secondPeak - firstPeak <= numBuckets >> 4) {
    e = BCExceptionRead;
    return 0;
  }
  int32_t bestValley = secondPeak - 1;
  int32_t bestValleyScore = -1;
  for (x = secondPeak - 1; x > firstPeak; x--) {
    int32_t fromFirst = x - firstPeak;
    int32_t score = fromFirst * fromFirst * (secondPeak - x) *
                    (maxBucketCount - buckets[x]);
    if (score > bestValleyScore) {
      bestValley = x;
      bestValleyScore = score;
    }
  }
  return bestValley << LUMINANCE_SHIFT;
}
