comparison mupdf-source/thirdparty/tesseract/src/classify/intfeaturespace.cpp @ 2:b50eed0cc0ef upstream

ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4. The directory name has changed: no version number in the expanded directory now.
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 15 Sep 2025 11:43:07 +0200
parents
children
comparison
equal deleted inserted replaced
1:1d09e1dec1d9 2:b50eed0cc0ef
1 // Copyright 2010 Google Inc. All Rights Reserved.
2 // Author: rays@google.com (Ray Smith)
3 ///////////////////////////////////////////////////////////////////////
4 // File: intfeaturespace.cpp
5 // Description: Indexed feature space based on INT_FEATURE_STRUCT.
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 ///////////////////////////////////////////////////////////////////////
18
19 #define _USE_MATH_DEFINES // for M_PI
20 #include "intfeaturespace.h"
21 #include <cmath> // for M_PI
22 #include "intfx.h"
23
24 namespace tesseract {
25
26 IntFeatureSpace::IntFeatureSpace() : x_buckets_(0), y_buckets_(0), theta_buckets_(0) {}
27
28 void IntFeatureSpace::Init(uint8_t xbuckets, uint8_t ybuckets, uint8_t thetabuckets) {
29 x_buckets_ = xbuckets;
30 y_buckets_ = ybuckets;
31 theta_buckets_ = thetabuckets;
32 }
33
34 // Serializes the feature space definition to the given file.
35 // Returns false on error.
36 bool IntFeatureSpace::Serialize(FILE *fp) const {
37 if (fwrite(&x_buckets_, sizeof(x_buckets_), 1, fp) != 1) {
38 return false;
39 }
40 if (fwrite(&y_buckets_, sizeof(y_buckets_), 1, fp) != 1) {
41 return false;
42 }
43 if (fwrite(&theta_buckets_, sizeof(theta_buckets_), 1, fp) != 1) {
44 return false;
45 }
46 return true;
47 }
48
49 // Returns an INT_FEATURE_STRUCT corresponding to the given index.
50 // This is the inverse of the Index member.
51 INT_FEATURE_STRUCT IntFeatureSpace::PositionFromIndex(int index) const {
52 return PositionFromBuckets(index / (y_buckets_ * theta_buckets_),
53 index / theta_buckets_ % y_buckets_, index % theta_buckets_);
54 }
55
56 // Bulk calls to Index. Maps the given array of features to a vector of
57 // int32_t indices in the same order as the input.
58 void IntFeatureSpace::IndexFeatures(const INT_FEATURE_STRUCT *features, int num_features,
59 std::vector<int> *mapped_features) const {
60 mapped_features->clear();
61 for (int f = 0; f < num_features; ++f) {
62 mapped_features->push_back(Index(features[f]));
63 }
64 }
65
66 // Bulk calls to Index. Maps the given array of features to a vector of
67 // sorted int32_t indices.
68 void IntFeatureSpace::IndexAndSortFeatures(const INT_FEATURE_STRUCT *features, int num_features,
69 std::vector<int> *sorted_features) const {
70 sorted_features->clear();
71 for (int f = 0; f < num_features; ++f) {
72 sorted_features->push_back(Index(features[f]));
73 }
74 std::sort(sorted_features->begin(), sorted_features->end());
75 }
76
77 // Returns a feature space index for the given x,y position in a display
78 // window, or -1 if the feature is a miss.
79 int IntFeatureSpace::XYToFeatureIndex(int x, int y) const {
80 // Round the x,y position to a feature. Search for a valid theta.
81 INT_FEATURE_STRUCT feature(x, y, 0);
82 int index = -1;
83 for (int theta = 0; theta <= UINT8_MAX && index < 0; ++theta) {
84 feature.Theta = theta;
85 index = Index(feature);
86 }
87 if (index < 0) {
88 tprintf("(%d,%d) does not exist in feature space!\n", x, y);
89 return -1;
90 }
91 feature = PositionFromIndex(index);
92 tprintf("Click at (%d, %d) ->(%d, %d), ->(%d, %d)\n", x, y, feature.X, feature.Y, x - feature.X,
93 y - feature.Y);
94 // Get the relative position of x,y from the rounded feature.
95 x -= feature.X;
96 y -= feature.Y;
97 if (x != 0 || y != 0) {
98 double angle = atan2(static_cast<double>(y), static_cast<double>(x)) + M_PI;
99 angle *= kIntFeatureExtent / (2.0 * M_PI);
100 feature.Theta = static_cast<uint8_t>(angle + 0.5);
101 index = Index(feature);
102 if (index < 0) {
103 tprintf("Feature failed to map to a valid index:");
104 feature.print();
105 return -1;
106 }
107 feature = PositionFromIndex(index);
108 }
109 feature.print();
110 return index;
111 }
112
113 // Returns an INT_FEATURE_STRUCT corresponding to the given bucket coords.
114 INT_FEATURE_STRUCT IntFeatureSpace::PositionFromBuckets(int x, int y, int theta) const {
115 INT_FEATURE_STRUCT pos((x * kIntFeatureExtent + kIntFeatureExtent / 2) / x_buckets_,
116 (y * kIntFeatureExtent + kIntFeatureExtent / 2) / y_buckets_,
117 DivRounded(theta * kIntFeatureExtent, theta_buckets_));
118 return pos;
119 }
120
121 } // namespace tesseract.