ronantakizawa/codereview-bench huggingface dataset:
Repository: tesseract-ocr/tesseract
File: src/ccstruct/tabletransfer.h (C/C++)

Code before:
/******************************************************************************
 * File:        tabletransfer.h
 * Description: Infrastructure for the transfer of table detection results
 * Author:      Sintun
 *
 * (C) Copyright 2021, Sintun
 * 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.
 *
 ****************************************************************************/

#pragma once
#include <memory>
#include <vector>
#include "rect.h"


/// Structure for data transfer from table detector 
struct MyTable {
  tesseract::TBOX box;
  std::vector<tesseract::TBOX> rows;
  std::vector<tesseract::TBOX> cols;
};

/** \brief You can use this small template function to ensure that one and
 *   only one object of type T exists. It implements the Singleton Pattern.
 *
 * T must be default-constructable.
 * Usage examples:
 *   A& a = uniqueInstance<A>();
 *   a.xyz();
 *   uniqueInstance<A>(make_unique<A>(42)); // replace instance
 *   a.foo();
 * or
 *   uniqueInstance<A>().xyz();
 */
template<typename T>
T& uniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
  static std::unique_ptr<T> _instance = std::make_unique<T>();

  if(new_instance)
    _instance = std::move(new_instance);

  return *_instance.get();
}

/// return const version of \see uniqueInstance
template<typename T>
const T& constUniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
  return uniqueInstance<T>(std::move(new_instance));
}


Review comment (suggestion):
```suggestion
}

#endif  // TESSERACT_CCSTRUCT_TABLETRANSFER_H_
```

Code after:
 * T must be default-constructable.
 * Usage examples:
 *   A& a = uniqueInstance<A>();
 *   a.xyz();
 *   uniqueInstance<A>(make_unique<A>(42)); // replace instance
 *   a.foo();
 * or
 *   uniqueInstance<A>().xyz();
 */
template<typename T>
T& uniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
  static std::unique_ptr<T> _instance = std::make_unique<T>();

  if(new_instance)
    _instance = std::move(new_instance);

  return *_instance.get();
}

/// return const version of \see uniqueInstance
template<typename T>
const T& constUniqueInstance(std::unique_ptr<T> new_instance = nullptr)
{
  return uniqueInstance<T>(std::move(new_instance));
}

} // namespace tesseract

#endif  // TESSERACT_CCSTRUCT_TABLETRANSFER_H_
Repository: tesseract-ocr/tesseract
File: src/textord/tablefind.cpp (C++)

Code before:
////////
ColSegment::ColSegment()
    : ELIST_LINK(), num_table_cells_(0), num_text_cells_(0), type_(COL_UNKNOWN) {}

// Provides a color for BBGrid to draw the rectangle.
ScrollView::Color ColSegment::BoxColor() const {
  const ScrollView::Color kBoxColors[PT_COUNT] = {
      ScrollView::YELLOW,
      ScrollView::BLUE,
      ScrollView::YELLOW,
      ScrollView::MAGENTA,
  };
  return kBoxColors[type_];
}

// Insert a box into this column segment
void ColSegment::InsertBox(const TBOX &other) {
  bounding_box_ = bounding_box_.bounding_union(other);
}

// Set column segment type based on the ratio of text and table partitions
// in it.
void ColSegment::set_type() {
  if (num_table_cells_ > kTableColumnThreshold * num_text_cells_)
    type_ = COL_TABLE;
  else if (num_text_cells_ > num_table_cells_)
    type_ = COL_TEXT;
  else
    type_ = COL_MIXED;
}

} // namespace tesseract.


Review comment (suggestion):
The following inserted block causes the assertion. Disabling that block fixes the regression.

Code after:
      // Include partition in the table if more than half of it
      // is covered by the table
      if (part_box.overlap_fraction(table_box) > kMinOverlapWithTable) {
        rectsearch.RemoveBBox();
        if (table_partition) {
          table_partition->Absorb(part, width_cb);
        } else {
          table_partition = part;
        }
      }
    }
    // Insert table colpartition back to part_grid_
    if (table_partition) {
      // To match the columns used when transforming to blocks, the new table
      // partition must have its first and last column set at the grid y that
      // corresponds to its bottom.
      const TBOX &table_box = table_partition->bounding_box();
      int grid_x, grid_y;
      grid->GridCoords(table_box.left(), table_box.bottom(), &grid_x, &grid_y);
      table_partition->SetPartitionType(resolution_, all_columns[grid_y]);
      table_partition->set_table_type();
      table_partition->set_blob_type(BRT_TEXT);
      table_partition->set_flow(BTFT_CHAIN);
      table_partition->SetBlobTypes();
      grid->InsertBBox(true, true, table_partition);
      
      // Insert table columns and rows into an api accessible object
      StructuredTable* table_structure = recognizer.RecognizeTable(table_box);
      if (table_structure != nullptr) {
#ifndef GRAPHICS_DISABLED
      if (textord_show_tables) {
        table_structure->Display(table_win, ScrollView::LIME_GREEN);
      }
#endif  // GRAPHICS_DISABLED

        std::vector<TessTable>& tables = uniqueInstance<std::vector<TessTable>>();
        tables.push_back(TessTable{table_box, table_structure->getRows(),
                                            table_structure->getCols()});
        
        delete table_structure;
      }
    }
  }
  
#ifndef GRAPHICS_DISABLED
  if (textord_show_tables) {
    table_grid_.DisplayBoxes(table_win);
  }
#endif  // GRAPHICS_DISABLED
}
Repository: tesseract-ocr/tesseract
File: src/ccutil/ccutil.cpp (C++)

Code before:
    /* Use tessdata prefix from the environment. */
    datadir = tessdata_prefix;
#if defined(_WIN32)
  } else if (datadir.empty() || _access(datadir.c_str(), 0) != 0) {
    /* Look for tessdata in directory of executable. */
    char path[_MAX_PATH];
    DWORD length = GetModuleFileName(nullptr, path, sizeof(path));
    if (length > 0 && length < sizeof(path)) {
      char *separator = std::strrchr(path, '\\');
      if (separator != nullptr) {
        *separator = '\0';
        std::string subdir = path;
        subdir += "/tessdata";
        if (_access(subdir.c_str(), 0) == 0) {
          datadir = subdir;
        }
      }
    }
#endif /* _WIN32 */
  }

  // datadir may still be empty:
  if (datadir.empty()) {
#if defined(TESSDATA_PREFIX)
    // Use tessdata prefix which was compiled in.
    // Note that some software (for example conda) patch TESSDATA_PREFIX
    // in the binary, so it should not be used directly with a std::string.
    tessdata_prefix = TESSDATA_PREFIX;
    datadir = tessdata_prefix;
    datadir += "/tessdata/";
#else
    datadir = "./";
#endif /* TESSDATA_PREFIX */
  }

  // check for missing directory separator
  const char lastchar = datadir.back();
  if (lastchar != '/' && lastchar != '\\') {
    datadir += '/';
  }
}

} // namespace tesseract


Review comment (suggestion):
```suggestion
    // Note that some software (for example conda) patches TESSDATA_PREFIX
```

Code after:
    /* Use tessdata prefix from the environment. */
    datadir = tessdata_prefix;
#if defined(_WIN32)
  } else if (datadir.empty() || _access(datadir.c_str(), 0) != 0) {
    /* Look for tessdata in directory of executable. */
    char path[_MAX_PATH];
    DWORD length = GetModuleFileName(nullptr, path, sizeof(path));
    if (length > 0 && length < sizeof(path)) {
      char *separator = std::strrchr(path, '\\');
      if (separator != nullptr) {
        *separator = '\0';
        std::string subdir = path;
        subdir += "/tessdata";
        if (_access(subdir.c_str(), 0) == 0) {
          datadir = subdir;
        }
      }
    }
#endif /* _WIN32 */
  }

  // datadir may still be empty:
  if (datadir.empty()) {
#if defined(TESSDATA_PREFIX)
    // Use tessdata prefix which was compiled in.
    // Note that some software (for example conda) patches TESSDATA_PREFIX
    // in the binary, so it should not be used directly with a std::string.
    tessdata_prefix = TESSDATA_PREFIX;
    datadir = tessdata_prefix;
    datadir += "/tessdata/";
#else
    datadir = "./";
#endif /* TESSDATA_PREFIX */
  }

  // check for missing directory separator
  const char lastchar = datadir.back();
  if (lastchar != '/' && lastchar != '\\') {
    datadir += '/';
  }
}

} // namespace tesseract
Repository: tesseract-ocr/tesseract
File: src/ccutil/tprintf.cpp (C++)

Code before:
#include "params.h"

#include <climits> // for INT_MAX
#include <cstdarg>
#include <cstdio>

namespace tesseract {

#define MAX_MSG_LEN 2048

INT_VAR(log_level, INT_MAX, "Logging level");

static STRING_VAR(debug_file, "", "File to send tprintf output to");

// Trace printf
void tprintf(const char *format, ...) {
  const char *debug_file_name = debug_file.c_str();
  static FILE *debugfp = nullptr; // debug file

  if (debug_file_name == nullptr) {
    // This should not happen.
    return;
  }

#ifdef _WIN32
  // Replace /dev/null by nul for Windows.
  if (strcmp(debug_file_name, "/dev/null") == 0) {
    debug_file_name = "nul";
    debug_file.set_value(debug_file_name);
  }
#endif

  if (debugfp == nullptr && debug_file_name[0] != '\0') {
    debugfp = fopen(debug_file_name, "wb");
  } else if (debugfp != nullptr && debug_file_name[0] == '\0') {
    fclose(debugfp);
    debugfp = nullptr;
  }

  va_list args;           // variable args
  va_start(args, format); // variable list
  if (debugfp != nullptr) {
    vfprintf(debugfp, format, args);
  } else {
    vfprintf(stderr, format, args);
  }
  va_end(args);
}

} // namespace tesseract


Review comment (refactor):
I wonder whether such use cases exist. We could simplify the code further if we only allow setting the desired output once before the first use of `tprintf`.

Code after:
#include "params.h"

#include <climits> // for INT_MAX
#include <cstdarg>
#include <cstdio>

namespace tesseract {

INT_VAR(log_level, INT_MAX, "Logging level");

static STRING_VAR(debug_file, "", "File to send tprintf output to");

// File for debug output.
static FILE *debugfp;

// Set output for log messages.
// The output is written to stderr if debug_file is empty.
// Otherwise it is written to debug_file.
// It is possible to switch between stderr and debug_file output:
// tprintf("write to configured output\n");
// debug_file = "";
// tprintf("write to stderr\n");
// debug_file = "/tmp/log";
// tprintf("write to /tmp/log\n");
// debug_file = "";
// tprintf("write to stderr\n");
static void set_debugfp() {
  if (debug_file.empty()) {
    // Write to stderr.
    if (debugfp != stderr && debugfp != nullptr) {
      fclose(debugfp);
    }
    debugfp = stderr;
  } else if (debugfp == stderr || debugfp == nullptr) {
    // Write to file.
#ifdef _WIN32
    if (debug_file == "/dev/null") {
      // Replace /dev/null by nul for Windows.
      debug_file = "nul";
    }
#endif
    debugfp = fopen(debug_file.c_str(), "wb");
  }
}

// Trace printf.
void tprintf(const char *format, ...) {
  set_debugfp();
  va_list args;           // variable args
  va_start(args, format); // variable list
  vfprintf(debugfp, format, args);
Repository: tesseract-ocr/tesseract
File: src/arch/intsimdmatrixrvv.cpp (C++)

Code before:
///////////////////////////////////////////////////////////////////////
// File:        intsimdmatrixrvv.cpp
// Description: matrix-vector product for 8-bit data on rvv.
// Author:      sunyuechi
//
// Copyright (c) 2024 Institue of Software Chinese Academy of Sciences (ISCAS).
// 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.
///////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG_H
#  include "config_auto.h" // for HAVE_RVV, ...
#endif

#if HAVE_RVV
#  include "intsimdmatrix.h"
#  include "tesstypes.h"

namespace tesseract {

// Number of outputs held in each register. 8 x 32 bit ints.
constexpr int kNumOutputsPerRegister = 1;
// Maximum number of registers that we will use.
constexpr int kMaxOutputRegisters = 1;

Review comment (suggestion):
```suggestion
// Copyright (c) 2024 Institute of Software Chinese Academy of Sciences (ISCAS).
```

Code after:
///////////////////////////////////////////////////////////////////////
// File:        intsimdmatrixrvv.cpp
// Description: matrix-vector product for 8-bit data on rvv.
// Author:      sunyuechi
//
// Copyright (c) 2024 Institute of Software Chinese Academy of Sciences (ISCAS).
// 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.
///////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG_H
#  include "config_auto.h" // for HAVE_RVV, ...
#endif

#if HAVE_RVV
#  include "intsimdmatrix.h"
#  include "tesstypes.h"

namespace tesseract {

static int DotProduct(const int8_t *u, const int8_t *v, int num) {
  int total = 0;

  asm __volatile__ (
Repository: tesseract-ocr/tesseract
File: src/arch/intsimdmatrixrvv.cpp (C++)

Code before:
    :  [u] "+r" (u),
       [v] "+r" (v),
       [num] "+r" (num),
       [total] "+r" (total)
    :
    :  "cc", "memory"
  );

  return total;
}

static void matrixDotVector(int dim1, int dim2, const int8_t *wi, const TFloat *scales,
                            const int8_t *u, TFloat *v) {
  int num_out = dim1;
  int num_in = dim2 - 1;
  for (int i = 0; i < num_out; ++i) {
    const int8_t *wi_start = wi + i * dim2;
    int total = 0;
    if (num_in < 4) {
      for (int j = 0; j < num_in; ++j) {
        total += u[j] * v[j];
      }
    } else {
      total = DotProduct(wi_start, u, num_in);
    }
    // Add in the bias and apply scaling.
    v[i] = (total + wi_start[num_in] * INT8_MAX) * scales[i];
  }
}

const IntSimdMatrix IntSimdMatrix::intSimdMatrixRVV = {
    // Function.
    matrixDotVector,
    // Number of 32 bit outputs held in each register.
    kNumOutputsPerRegister,
    // Maximum number of registers that we will use to hold outputs.
    kMaxOutputRegisters,
    // Number of 8 bit inputs in the inputs register.
    kNumInputsPerRegister,
    // Number of inputs in each weight group.
    kNumInputsPerGroup
};

} // namespace tesseract.

#endif /* HAVE_RVV */


Review comment (suggestion):
```suggestion
const IntSimdMatrix IntSimdMatrix::intSimdMatrixRVV = {
    // Function.
    matrixDotVector,
    // Number of 32 bit outputs held in each register.
    1,
    // Maximum number of registers that we will use to hold outputs.
    1,
    // Number of 8 bit inputs in the inputs register.
    1,
    // Number of inputs in each weight group.
    1
};
```

Code after:
}

static void matrixDotVector(int dim1, int dim2, const int8_t *wi, const TFloat *scales,
                            const int8_t *u, TFloat *v) {
  int num_out = dim1;
  int num_in = dim2 - 1;
  for (int i = 0; i < num_out; ++i) {
    const int8_t *wi_start = wi + i * dim2;
    int total = DotProduct(wi_start, u, num_in);
    // Add in the bias and apply scaling.
    v[i] = (total + wi_start[num_in] * INT8_MAX) * scales[i];
  }
}

const IntSimdMatrix IntSimdMatrix::intSimdMatrixRVV = {
    // Function.
    matrixDotVector,
    // Number of 32 bit outputs held in each register.
    1,
    // Maximum number of registers that we will use to hold outputs.
    1,
    // Number of 8 bit inputs in the inputs register.
    1,
    // Number of inputs in each weight group.
    1
};

} // namespace tesseract.

#endif /* HAVE_RVV */
Repository: tesseract-ocr/tesseract
File: src/arch/intsimdmatrixrvv.cpp (C++)

Code before:
///////////////////////////////////////////////////////////////////////
// File:        intsimdmatrixrvv.cpp
// Description: matrix-vector product for 8-bit data on rvv.
// Author:      sunyuechi
//
// Copyright (c) 2024 Institue of Software Chinese Academy of Sciences (ISCAS).
// 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.
///////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG_H
#  include "config_auto.h" // for HAVE_RVV, ...
#endif

#if HAVE_RVV
#  include "intsimdmatrix.h"
#  include "tesstypes.h"

namespace tesseract {

static int DotProduct(const int8_t *u, const int8_t *v, int num) {
  int total = 0;

  asm __volatile__ (

Review comment (suggestion):
```suggestion
// Copyright (c) 2024 Institute of Software Chinese Academy of Sciences (ISCAS).
```

Code after:
///////////////////////////////////////////////////////////////////////
// File:        intsimdmatrixrvv.cpp
// Description: matrix-vector product for 8-bit data on rvv.
// Author:      sunyuechi
//
// Copyright (c) 2024 Institute of Software Chinese Academy of Sciences (ISCAS).
// 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.
///////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG_H
#  include "config_auto.h" // for HAVE_RVV, ...
#endif

#if HAVE_RVV
#  include "intsimdmatrix.h"
#  include "tesstypes.h"

namespace tesseract {

static int DotProduct(const int8_t *u, const int8_t *v, int num) {
  int total = 0;

  asm __volatile__ (
Repository: tesseract-ocr/tesseract
File: src/api/altorenderer.cpp (C++)

Code before:
/// Add word confidence if adding to a String bounding box.
///
static void AddBoxToAlto(const ResultIterator *it, PageIteratorLevel level,
                         std::stringstream &alto_str) {
  int left, top, right, bottom;
  it->BoundingBox(level, &left, &top, &right, &bottom);

  int hpos = left;
  int vpos = top;
  int height = bottom - top;
  int width = right - left;

  alto_str << " HPOS=\"" << hpos << "\"";
  alto_str << " VPOS=\"" << vpos << "\"";
  alto_str << " WIDTH=\"" << width << "\"";
  alto_str << " HEIGHT=\"" << height << "\"";

  if (level == RIL_WORD) {
    int wc = it->Confidence(RIL_WORD);
    alto_str << " WC=\"0." << wc << "\"";
  } else {
    alto_str << ">";
  }
}

static std::string GetID(char const * prefix, int page_number, int counter) {
  std::stringstream idstr;
  // IDs will only have the counter for the first page to keep them consistent
  // with the IDs assigned before this change was made.
  // From the second page on, IDs will also contain the page number to make them unique.
  if (page_number == 0) {
    idstr << prefix << "_" << counter;
  } else {
    idstr << prefix << "_" << page_number << "_" << counter;
  }

  return idstr.str();
}

///
/// Append the ALTO XML for the beginning of the document
///
bool TessAltoRenderer::BeginDocumentHandler() {
  // Delay the XML output because we need the name of the image file.
  begin_document = true;
  return true;
}

///
/// Append the ALTO XML for the layout of the image
///

Review comment (suggestion):
```suggestion
static std::string GetID(const char *prefix, int page_number, int counter) {
```

Code after:
/// Add word confidence if adding to a String bounding box.
///
static void AddBoxToAlto(const ResultIterator *it, PageIteratorLevel level,
                         std::stringstream &alto_str) {
  int left, top, right, bottom;
  it->BoundingBox(level, &left, &top, &right, &bottom);

  int hpos = left;
  int vpos = top;
  int height = bottom - top;
  int width = right - left;

  alto_str << " HPOS=\"" << hpos << "\"";
  alto_str << " VPOS=\"" << vpos << "\"";
  alto_str << " WIDTH=\"" << width << "\"";
  alto_str << " HEIGHT=\"" << height << "\"";

  if (level == RIL_WORD) {
    int wc = it->Confidence(RIL_WORD);
    alto_str << " WC=\"0." << wc << "\"";
  } else {
    alto_str << ">";
  }
}

static std::string GetID(const char *prefix, int page_number, int counter) {
  std::stringstream idstr;
  // IDs will only have the counter for the first page to keep them consistent
  // with the IDs assigned before this change was made.
  // From the second page on, IDs will also contain the page number to make them unique.
  if (page_number == 0) {
    idstr << prefix << "_" << counter;
  } else {
    idstr << prefix << "_" << page_number << "_" << counter;
  }

  return idstr.str();
}

///
/// Append the ALTO XML for the beginning of the document
///
bool TessAltoRenderer::BeginDocumentHandler() {
  // Delay the XML output because we need the name of the image file.
  begin_document = true;
  return true;
}

///
/// Append the ALTO XML for the layout of the image
///