Commit a4566d17 for tesseract

commit a4566d170e4d420da5197c13f7e609edb7177f9f
Author: Stefan Weil <sw@weilnetz.de>
Date:   Thu Jun 18 23:01:13 2026 +0200

    Replace C-style INT_FEATURE_ARRAY with std::array

    Change the INT_FEATURE_ARRAY typedef from a raw C-style array
    to std::array<INT_FEATURE_STRUCT, MAX_NUM_INT_FEATURES>.

    This provides:
    - Automatic memory management
    - Bounds checking in debug builds
    - Value semantics without decay to pointer
    - Clear ownership semantics

    Update function signatures to use const references where appropriate:
    - IntegerMatcher::FindGoodProtos
    - IntegerMatcher::FindBadFeatures
    - Classify::ComputeIntFeatures
    - Classify::MakeNewTemporaryConfig

    Use .data() at call site for functions expecting raw pointers
    (e.g., Match function).

    GetAdaptiveFeatures uses a non-const reference because it
    modifies the array via ComputeIntFeatures.

    Build verified successfully.

    Assisted-by: minimax-m2.7 (MiniMax)
    Signed-off-by: Stefan Weil <sw@weilnetz.de>

diff --git a/src/classify/adaptmatch.cpp b/src/classify/adaptmatch.cpp
index f71d86d8..7195dacd 100644
--- a/src/classify/adaptmatch.cpp
+++ b/src/classify/adaptmatch.cpp
@@ -775,7 +775,7 @@ void Classify::InitAdaptedClass(TBLOB *Blob, CLASS_ID ClassId, int FontinfoId, A
  * @return Number of pico-features returned (0 if
  * an error occurred)
  */
-int Classify::GetAdaptiveFeatures(TBLOB *Blob, INT_FEATURE_ARRAY IntFeatures,
+int Classify::GetAdaptiveFeatures(TBLOB *Blob, INT_FEATURE_ARRAY &IntFeatures,
                                   FEATURE_SET *FloatFeatures) {
   FEATURE_SET Features;
   int NumFeatures;
@@ -877,7 +877,7 @@ void Classify::AdaptToChar(TBLOB *Blob, CLASS_ID ClassId, int FontinfoId, float
         reset_bit(MatchingFontConfigs, cfg);
       }
     }
-    im_.Match(IClass, AllProtosOn, MatchingFontConfigs, NumFeatures, IntFeatures, &int_result,
+    im_.Match(IClass, AllProtosOn, MatchingFontConfigs, NumFeatures, IntFeatures.data(), &int_result,
               classify_adapt_feature_threshold, NO_DEBUG, matcher_debug_separate_windows);
     FreeBitVector(MatchingFontConfigs);

@@ -1667,7 +1667,7 @@ void Classify::ComputeCharNormArrays(FEATURE_STRUCT *norm_feature, INT_TEMPLATES
  * case of error.
  */
 int Classify::MakeNewTemporaryConfig(ADAPT_TEMPLATES_STRUCT *Templates, CLASS_ID ClassId, int FontinfoId,
-                                     int NumFeatures, INT_FEATURE_ARRAY Features,
+                                     int NumFeatures, const INT_FEATURE_ARRAY &Features,
                                      FEATURE_SET FloatFeatures) {
   INT_CLASS_STRUCT *IClass;
   ADAPT_CLASS_STRUCT *Class;
diff --git a/src/classify/classify.h b/src/classify/classify.h
index e03b8f79..15ab9f67 100644
--- a/src/classify/classify.h
+++ b/src/classify/classify.h
@@ -193,7 +193,7 @@ public:
   void ConvertMatchesToChoices(const DENORM &denorm, const TBOX &box, ADAPT_RESULTS *Results,
                                BLOB_CHOICE_LIST *Choices);
   void AddNewResult(const UnicharRating &new_result, ADAPT_RESULTS *results);
-  int GetAdaptiveFeatures(TBLOB *Blob, INT_FEATURE_ARRAY IntFeatures, FEATURE_SET *FloatFeatures);
+  int GetAdaptiveFeatures(TBLOB *Blob, INT_FEATURE_ARRAY &IntFeatures, FEATURE_SET *FloatFeatures);

 #  ifndef GRAPHICS_DISABLED
   void DebugAdaptiveClassifier(TBLOB *Blob, ADAPT_RESULTS *Results);
@@ -201,7 +201,7 @@ public:
   PROTO_ID MakeNewTempProtos(FEATURE_SET Features, int NumBadFeat, FEATURE_ID BadFeat[],
                              INT_CLASS_STRUCT *IClass, ADAPT_CLASS_STRUCT *Class, BIT_VECTOR TempProtoMask);
   int MakeNewTemporaryConfig(ADAPT_TEMPLATES_STRUCT *Templates, CLASS_ID ClassId, int FontinfoId,
-                             int NumFeatures, INT_FEATURE_ARRAY Features,
+                             int NumFeatures, const INT_FEATURE_ARRAY &Features,
                              FEATURE_SET FloatFeatures);
   void MakePermanent(ADAPT_TEMPLATES_STRUCT *Templates, CLASS_ID ClassId, int ConfigId, TBLOB *Blob);
   void PrintAdaptiveMatchResults(const ADAPT_RESULTS &results);
@@ -313,7 +313,7 @@ public:
   /* float2int.cpp ************************************************************/
   void ClearCharNormArray(uint8_t *char_norm_array);
   void ComputeIntCharNormArray(const FEATURE_STRUCT &norm_feature, uint8_t *char_norm_array);
-  void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures);
+  void ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY &IntFeatures);
   /* intproto.cpp *************************************************************/
   INT_TEMPLATES_STRUCT *ReadIntTemplates(TFile *fp);
   void WriteIntTemplates(FILE *File, INT_TEMPLATES_STRUCT *Templates, const UNICHARSET &target_unicharset);
diff --git a/src/classify/float2int.cpp b/src/classify/float2int.cpp
index cb47e648..d2596a97 100644
--- a/src/classify/float2int.cpp
+++ b/src/classify/float2int.cpp
@@ -82,7 +82,7 @@ void Classify::ComputeIntCharNormArray(const FEATURE_STRUCT &norm_feature,
  * @param Features floating point pico-features to be converted
  * @param[out] IntFeatures array to put converted features into
  */
-void Classify::ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY IntFeatures) {
+void Classify::ComputeIntFeatures(FEATURE_SET Features, INT_FEATURE_ARRAY &IntFeatures) {
   float YShift;

   if (classify_norm_method == baseline) {
diff --git a/src/classify/intmatcher.cpp b/src/classify/intmatcher.cpp
index 5e5d1a0e..d4b81c56 100644
--- a/src/classify/intmatcher.cpp
+++ b/src/classify/intmatcher.cpp
@@ -549,7 +549,7 @@ void IntegerMatcher::Match(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR ProtoMask
  */
 int IntegerMatcher::FindGoodProtos(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR ProtoMask,
                                    BIT_VECTOR ConfigMask, int16_t NumFeatures,
-                                   INT_FEATURE_ARRAY Features, PROTO_ID *ProtoArray,
+                                   const INT_FEATURE_ARRAY &Features, PROTO_ID *ProtoArray,
                                    int AdaptProtoThreshold, int Debug) {
   auto *tables = new ScratchEvidence();
   int NumGoodProtos = 0;
@@ -613,7 +613,7 @@ int IntegerMatcher::FindGoodProtos(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR P
  */
 int IntegerMatcher::FindBadFeatures(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR ProtoMask,
                                     BIT_VECTOR ConfigMask, int16_t NumFeatures,
-                                    INT_FEATURE_ARRAY Features, FEATURE_ID *FeatureArray,
+                                    const INT_FEATURE_ARRAY &Features, FEATURE_ID *FeatureArray,
                                     int AdaptFeatureThreshold, int Debug) {
   auto *tables = new ScratchEvidence();
   int NumBadFeatures = 0;
diff --git a/src/classify/intmatcher.h b/src/classify/intmatcher.h
index d7dd0c1f..d735fb23 100644
--- a/src/classify/intmatcher.h
+++ b/src/classify/intmatcher.h
@@ -88,11 +88,11 @@ public:
                           int matcher_multiplier);

   int FindGoodProtos(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR ProtoMask, BIT_VECTOR ConfigMask,
-                     int16_t NumFeatures, INT_FEATURE_ARRAY Features, PROTO_ID *ProtoArray,
+                     int16_t NumFeatures, const INT_FEATURE_ARRAY &Features, PROTO_ID *ProtoArray,
                      int AdaptProtoThreshold, int Debug);

   int FindBadFeatures(INT_CLASS_STRUCT *ClassTemplate, BIT_VECTOR ProtoMask, BIT_VECTOR ConfigMask,
-                      int16_t NumFeatures, INT_FEATURE_ARRAY Features, FEATURE_ID *FeatureArray,
+                      int16_t NumFeatures, const INT_FEATURE_ARRAY &Features, FEATURE_ID *FeatureArray,
                       int AdaptFeatureThreshold, int Debug);

 private:
diff --git a/src/classify/intproto.h b/src/classify/intproto.h
index a90e43cb..ef1bd73e 100644
--- a/src/classify/intproto.h
+++ b/src/classify/intproto.h
@@ -20,13 +20,15 @@

 /**----------------------------------------------------------------------------
           Include Files and Type Defines
-----------------------------------------------------------------------------**/
+ ----------------------------------------------------------------------------**/
 #include "matchdefs.h"
 #include "mfoutline.h"
 #include "protos.h"
 #include "scrollview.h"
 #include "unicharset.h"

+#include <array>
+
 namespace tesseract {

 class FCOORD;
@@ -134,7 +136,7 @@ struct INT_FEATURE_STRUCT {
   }
 };

-typedef INT_FEATURE_STRUCT INT_FEATURE_ARRAY[MAX_NUM_INT_FEATURES];
+typedef std::array<INT_FEATURE_STRUCT, MAX_NUM_INT_FEATURES> INT_FEATURE_ARRAY;

 enum IntmatcherDebugAction { IDA_ADAPTIVE, IDA_STATIC, IDA_SHAPE_INDEX, IDA_BOTH };