tesseract v5.3.3.20231005
imagedata_test.cc
Go to the documentation of this file.
1// (C) Copyright 2017, Google Inc.
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5// http://www.apache.org/licenses/LICENSE-2.0
6// Unless required by applicable law or agreed to in writing, software
7// distributed under the License is distributed on an "AS IS" BASIS,
8// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9// See the License for the specific language governing permissions and
10// limitations under the License.
11
12#include <string>
13#include <vector>
14
15#include "imagedata.h"
16#include "include_gunit.h"
17#include "log.h"
18
19namespace tesseract {
20
21// Tests the caching mechanism of DocumentData/ImageData.
22
24protected:
25 void SetUp() override {
26 std::locale::global(std::locale(""));
28 }
29
30 ImagedataTest() = default;
31
32 // Creates a fake DocumentData, writes it to a file, and returns the filename.
33 std::string MakeFakeDoc(int num_pages, unsigned doc_id, std::vector<std::string> *page_texts) {
34 // The size of the fake images that we will use.
35 const int kImageSize = 1048576;
36 // Not using a real image here - just an array of zeros! We are just testing
37 // that the truth text matches.
38 std::vector<char> fake_image(kImageSize, 0);
39 DocumentData write_doc("My document");
40 for (int p = 0; p < num_pages; ++p) {
41 // Make some fake text that is different for each page and save it.
42 char text[80];
43 snprintf(text, sizeof(text), "Page %d of %d in doc %u", p, num_pages, doc_id);
44 page_texts->push_back(text);
45 // Make an imagedata and put it in the document.
46 ImageData *imagedata = ImageData::Build("noname", p, "eng", fake_image.data(),
47 fake_image.size(), (*page_texts)[p].c_str(), nullptr);
48 EXPECT_EQ(kImageSize, imagedata->MemoryUsed());
49 write_doc.AddPageToDocument(imagedata);
50 }
51 // Write it to a file.
52 std::string filename =
53 file::JoinPath(FLAGS_test_tmpdir, "documentdata");
54 filename += std::to_string(doc_id) + ".lstmf";
55 EXPECT_TRUE(write_doc.SaveDocument(filename.c_str(), nullptr));
56 return filename;
57 }
58};
59
60TEST_F(ImagedataTest, CachesProperly) {
61 // This test verifies that Imagedata can be stored in a DocumentData and a
62 // collection of them is cached correctly given limited memory.
63 // Number of pages to put in the fake document.
64 const int kNumPages = 12;
65 // Allowances to read the document. Big enough for 1, 3, 0, all pages.
66 const int kMemoryAllowances[] = {2000000, 4000000, 1000000, 100000000, 0};
67 // Order in which to read the pages, with some sequential and some seeks.
68 const int kPageReadOrder[] = {0, 1, 2, 3, 8, 4, 5, 6, 7, 11, 10, 9, -1};
69
70 std::vector<std::string> page_texts;
71 std::string filename = MakeFakeDoc(kNumPages, 0, &page_texts);
72 // Now try getting it back with different memory allowances and check that
73 // the pages can still be read.
74 for (int m = 0; kMemoryAllowances[m] > 0; ++m) {
75 DocumentData read_doc("My document");
76 EXPECT_TRUE(read_doc.LoadDocument(filename.c_str(), 0, kMemoryAllowances[m], nullptr));
77 LOG(ERROR) << "Allowance = " << kMemoryAllowances[m];
78 // Read the pages in a specific order.
79 for (int p = 0; kPageReadOrder[p] >= 0; ++p) {
80 int page = kPageReadOrder[p];
81 const ImageData *imagedata = read_doc.GetPage(page);
82 EXPECT_NE(nullptr, imagedata);
83 // EXPECT_NE(reinterpret_cast<ImageData*>(nullptr), imagedata);
84 // Check that this is the right page.
85 EXPECT_STREQ(page_texts[page].c_str(), imagedata->transcription().c_str());
86 }
87 }
88}
89
90TEST_F(ImagedataTest, CachesMultiDocs) {
91 // This test verifies that DocumentCache works to store multiple DocumentData
92 // and the two caching strategies read images in the right order.
93 // Number of pages in each document.
94 const std::vector<int> kNumPages = {6, 5, 7};
95 std::vector<std::vector<std::string>> page_texts;
96 std::vector<std::string> filenames;
97 for (size_t d = 0; d < kNumPages.size(); ++d) {
98 page_texts.emplace_back(std::vector<std::string>());
99 std::string filename = MakeFakeDoc(kNumPages[d], d, &page_texts.back());
100 filenames.push_back(filename);
101 }
102 // Now try getting them back with different cache strategies and check that
103 // the pages come out in the right order.
104 DocumentCache robin_cache(8000000);
105 robin_cache.LoadDocuments(filenames, tesseract::CS_ROUND_ROBIN, nullptr);
106 DocumentCache serial_cache(8000000);
107 serial_cache.LoadDocuments(filenames, tesseract::CS_SEQUENTIAL, nullptr);
108 for (int p = 0; p <= 21; ++p) {
109 LOG(INFO) << "Page " << p;
110 const ImageData *robin_data = robin_cache.GetPageBySerial(p);
111 const ImageData *serial_data = serial_cache.GetPageBySerial(p);
112 CHECK(robin_data != nullptr);
113 CHECK(serial_data != nullptr);
114 int robin_doc = p % kNumPages.size();
115 int robin_page = p / kNumPages.size() % kNumPages[robin_doc];
116 // Check that this is the right page.
117 EXPECT_STREQ(page_texts[robin_doc][robin_page].c_str(), robin_data->transcription().c_str());
118 int serial_doc = p / kNumPages[0] % kNumPages.size();
119 int serial_page = p % kNumPages[0] % kNumPages[serial_doc];
120 EXPECT_STREQ(page_texts[serial_doc][serial_page].c_str(), serial_data->transcription().c_str());
121 }
122}
123
124} // namespace tesseract
@ LOG
@ ERROR
Definition: log.h:28
@ INFO
Definition: log.h:28
const char * p
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:2043
#define EXPECT_NE(val1, val2)
Definition: gtest.h:2045
#define EXPECT_TRUE(condition)
Definition: gtest.h:1982
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:2112
#define CHECK(condition)
Definition: include_gunit.h:76
@ CS_SEQUENTIAL
Definition: imagedata.h:49
@ CS_ROUND_ROBIN
Definition: imagedata.h:54
TEST_F(EuroText, FastLatinOCR)
const std::string & transcription() const
Definition: imagedata.h:104
static ImageData * Build(const char *name, int page_number, const char *lang, const char *imagedata, int imagedatasize, const char *truth_text, const char *box_text)
Definition: imagedata.cpp:58
int MemoryUsed() const
Definition: imagedata.cpp:268
TESS_API bool SaveDocument(const char *filename, FileWriter writer)
Definition: imagedata.cpp:421
TESS_API bool LoadDocument(const char *filename, int start_page, int64_t max_memory, FileReader reader)
Definition: imagedata.cpp:402
TESS_API const ImageData * GetPage(int index)
Definition: imagedata.cpp:467
TESS_API void AddPageToDocument(ImageData *page)
Definition: imagedata.cpp:433
const ImageData * GetPageBySerial(int serial)
Definition: imagedata.h:317
TESS_API bool LoadDocuments(const std::vector< std::string > &filenames, CachingStrategy cache_strategy, FileReader reader)
Definition: imagedata.cpp:614
std::string MakeFakeDoc(int num_pages, unsigned doc_id, std::vector< std::string > *page_texts)
static void MakeTmpdir()
Definition: include_gunit.h:38
static std::string JoinPath(const std::string &s1, const std::string &s2)
Definition: include_gunit.h:65