mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2024-11-27 20:59:36 +08:00
7ebd3153ae
Signed-off-by: Stefan Weil <sw@weilnetz.de>
115 lines
3.6 KiB
C++
115 lines
3.6 KiB
C++
// (C) Copyright 2017, Google Inc.
|
|
// 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 <cmath>
|
|
#include <cstdio>
|
|
#include <string>
|
|
|
|
#include "indexmapbidi.h"
|
|
|
|
#include "include_gunit.h"
|
|
|
|
using tesseract::IndexMap;
|
|
using tesseract::IndexMapBiDi;
|
|
|
|
const int kPrimeLimit = 1000;
|
|
|
|
namespace {
|
|
|
|
class IndexMapBiDiTest : public testing::Test {
|
|
public:
|
|
std::string OutputNameToPath(const std::string& name) {
|
|
return file::JoinPath(FLAGS_test_tmpdir, name);
|
|
}
|
|
// Computes primes up to kPrimeLimit, using the sieve of Eratosthenes.
|
|
void ComputePrimes(IndexMapBiDi* map) {
|
|
map->Init(kPrimeLimit + 1, false);
|
|
map->SetMap(2, true);
|
|
// Set all the odds to true.
|
|
for (int i = 3; i <= kPrimeLimit; i += 2) map->SetMap(i, true);
|
|
int factor_limit = static_cast<int>(sqrt(1.0 + kPrimeLimit));
|
|
for (int f = 3; f <= factor_limit; f += 2) {
|
|
if (map->SparseToCompact(f) >= 0) {
|
|
for (int m = 2; m * f <= kPrimeLimit; ++m) map->SetMap(f * m, false);
|
|
}
|
|
}
|
|
map->Setup();
|
|
}
|
|
|
|
void TestPrimes(const IndexMap& map) {
|
|
// Now all primes are mapped in the sparse map to their index.
|
|
// According to Wikipedia, the 168th prime is 997, and it has compact
|
|
// index 167 because we are indexing from 0.
|
|
EXPECT_EQ(167, map.SparseToCompact(997));
|
|
EXPECT_EQ(997, map.CompactToSparse(167));
|
|
// 995, 996, 998, 999 are not prime.
|
|
EXPECT_EQ(-1, map.SparseToCompact(995));
|
|
EXPECT_EQ(-1, map.SparseToCompact(996));
|
|
EXPECT_EQ(-1, map.SparseToCompact(998));
|
|
EXPECT_EQ(-1, map.SparseToCompact(999));
|
|
// The 167th prime is 991.
|
|
EXPECT_EQ(991, map.CompactToSparse(166));
|
|
// There are 168 primes in 0..1000.
|
|
EXPECT_EQ(168, map.CompactSize());
|
|
EXPECT_EQ(kPrimeLimit + 1, map.SparseSize());
|
|
}
|
|
};
|
|
|
|
// Tests the sieve of Eratosthenes as a way of testing setup.
|
|
TEST_F(IndexMapBiDiTest, Primes) {
|
|
IndexMapBiDi map;
|
|
ComputePrimes(&map);
|
|
TestPrimes(map);
|
|
// It still works if we assign it to another.
|
|
IndexMapBiDi map2;
|
|
map2.CopyFrom(map);
|
|
TestPrimes(map2);
|
|
// Or if we assign it to a base class.
|
|
IndexMap base_map;
|
|
base_map.CopyFrom(map);
|
|
TestPrimes(base_map);
|
|
// Test file i/o too.
|
|
std::string filename = OutputNameToPath("primesmap");
|
|
FILE* fp = fopen(filename.c_str(), "wb");
|
|
CHECK(fp != nullptr);
|
|
EXPECT_TRUE(map.Serialize(fp));
|
|
fclose(fp);
|
|
fp = fopen(filename.c_str(), "rb");
|
|
CHECK(fp != nullptr);
|
|
IndexMapBiDi read_map;
|
|
EXPECT_TRUE(read_map.DeSerialize(false, fp));
|
|
fclose(fp);
|
|
TestPrimes(read_map);
|
|
}
|
|
|
|
// Tests the many-to-one setup feature.
|
|
TEST_F(IndexMapBiDiTest, ManyToOne) {
|
|
// Test the example in the comment on CompleteMerges.
|
|
IndexMapBiDi map;
|
|
map.Init(13, false);
|
|
map.SetMap(2, true);
|
|
map.SetMap(4, true);
|
|
map.SetMap(7, true);
|
|
map.SetMap(9, true);
|
|
map.SetMap(11, true);
|
|
map.Setup();
|
|
map.Merge(map.SparseToCompact(2), map.SparseToCompact(9));
|
|
map.Merge(map.SparseToCompact(4), map.SparseToCompact(11));
|
|
map.CompleteMerges();
|
|
EXPECT_EQ(3, map.CompactSize());
|
|
EXPECT_EQ(13, map.SparseSize());
|
|
EXPECT_EQ(1, map.SparseToCompact(4));
|
|
EXPECT_EQ(4, map.CompactToSparse(1));
|
|
EXPECT_EQ(1, map.SparseToCompact(11));
|
|
}
|
|
|
|
} // namespace.
|