Repository: tesseract-ocr/tesseract
File: src/ccmain/thresholder.cpp (C++)

Code before:
    if (depth > 1 && depth < 8) {
      pix_ = pixConvertTo8(tmp, false);
      tmp.destroy();
    } else {
      pix_ = tmp;
    }
  } else if (depth > 1 && depth < 8) {
    pix_ = pixConvertTo8(src, false);
  } else {
    pix_ = src.copy();
  }
  depth = pixGetDepth(pix_);
  pix_channels_ = depth / 8;
  pix_wpl_ = pixGetWpl(pix_);
  scale_ = 1;
  estimated_res_ = yres_ = pixGetYRes(pix_);
  Init();
}

std::tuple<bool, Image, Image, Image> ImageThresholder::Threshold(
                                                         ThresholdMethod method) {
  Image pix_grey = nullptr;
  Image pix_binary = nullptr;
  Image pix_thresholds = nullptr;

  if (image_width_ > INT16_MAX || image_height_ > INT16_MAX) {
    tprintf("Image too large: (%d, %d)\n", image_width_, image_height_);
    return std::make_tuple(false, nullptr, nullptr, nullptr);
  }

  if (pix_channels_ == 0) {
    // We have a binary image, but it still has to be copied, as this API
    // allows the caller to modify the output.
    Image original = GetPixRect();
    pix_binary = original.copy();
    original.destroy();
    return std::make_tuple(false, nullptr, pix_binary, nullptr);
  }

  pix_grey = GetPixRectGrey();

  if (method == ThresholdMethod::Otsu || method >= ThresholdMethod::Max) {
    method = ThresholdMethod::AdaptiveOtsu;
  }

  int r;
  if (method == ThresholdMethod::AdaptiveOtsu) {
    r = pixOtsuAdaptiveThreshold(pix_grey, 300, 300, 0, 0, 0.1,
                                 pix_thresholds, pix_binary);
  } else if (method == ThresholdMethod::TiledSauvola) {
    r = pixSauvolaBinarizeTiled(pix_grey, 25, 0.40, 300, 300, pix_thresholds,

Review comment (suggestion):
As I said elsewhere, this block was copied from another function in the same file. You should delete the other block too.

Code after:
    if (depth > 1 && depth < 8) {
      pix_ = pixConvertTo8(tmp, false);
      tmp.destroy();
    } else {
      pix_ = tmp;
    }
  } else if (depth > 1 && depth < 8) {
    pix_ = pixConvertTo8(src, false);
  } else {
    pix_ = src.copy();
  }
  depth = pixGetDepth(pix_);
  pix_channels_ = depth / 8;
  pix_wpl_ = pixGetWpl(pix_);
  scale_ = 1;
  estimated_res_ = yres_ = pixGetYRes(pix_);
  Init();
}

std::tuple<bool, Image, Image, Image> ImageThresholder::Threshold(
                                                         ThresholdMethod method) {
  Image pix_binary = nullptr;
  Image pix_thresholds = nullptr;

  if (pix_channels_ == 0) {
    // We have a binary image, but it still has to be copied, as this API
    // allows the caller to modify the output.
    Image original = GetPixRect();
    pix_binary = original.copy();
    original.destroy();
    return std::make_tuple(false, nullptr, pix_binary, nullptr);
  }

  auto pix_grey = GetPixRectGrey();

  int r;
  if (method == ThresholdMethod::TiledSauvola) {
    r = pixSauvolaBinarizeTiled(pix_grey, 25, 0.40, 300, 300, pix_thresholds,
                                pix_binary);
  } else {
    // AdaptiveOtsu.
    r = pixOtsuAdaptiveThreshold(pix_grey, 300, 300, 0, 0, 0.1,
                                 pix_thresholds, pix_binary);
  }

  bool ok = (r == 0);
  return std::make_tuple(ok, pix_grey, pix_binary, pix_thresholds);
}

// Threshold the source image as efficiently as possible to the output Pix.
// Creates a Pix and sets pix to point to the resulting pointer.