tesseract  5.0.0-alpha-619-ge9db
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 "absl/strings/str_cat.h"
16 #include "absl/strings/str_format.h"
17 
18 #include "imagedata.h"
19 #include "include_gunit.h"
20 #include "log.h"
21 
25 
26 namespace {
27 
28 // Tests the caching mechanism of DocumentData/ImageData.
29 
30 class ImagedataTest : public ::testing::Test {
31  protected:
32  void SetUp() {
33  std::locale::global(std::locale(""));
34  }
35 
36  ImagedataTest() {}
37 
38  // Creates a fake DocumentData, writes it to a file, and returns the filename.
39  std::string MakeFakeDoc(int num_pages, unsigned doc_id,
40  std::vector<std::string>* page_texts) {
41  // The size of the fake images that we will use.
42  const int kImageSize = 1048576;
43  // Not using a real image here - just an array of zeros! We are just testing
44  // that the truth text matches.
45  std::vector<char> fake_image(kImageSize, 0);
46  DocumentData write_doc("My document");
47  for (int p = 0; p < num_pages; ++p) {
48  // Make some fake text that is different for each page and save it.
49  page_texts->push_back(
50  absl::StrFormat("Page %d of %d in doc %u", p, num_pages, doc_id));
51  // Make an imagedata and put it in the document.
52  ImageData* imagedata =
53  ImageData::Build("noname", p, "eng", fake_image.data(),
54  fake_image.size(), (*page_texts)[p].c_str(), nullptr);
55  EXPECT_EQ(kImageSize, imagedata->MemoryUsed());
56  write_doc.AddPageToDocument(imagedata);
57  }
58  // Write it to a file.
59  std::string filename = file::JoinPath(
60  FLAGS_test_tmpdir, absl::StrCat("documentdata", doc_id, ".lstmf"));
61  EXPECT_TRUE(write_doc.SaveDocument(filename.c_str(), nullptr));
62  return filename;
63  }
64 };
65 
66 TEST_F(ImagedataTest, CachesProperly) {
67  // This test verifies that Imagedata can be stored in a DocumentData and a
68  // collection of them is cached correctly given limited memory.
69  // Number of pages to put in the fake document.
70  const int kNumPages = 12;
71  // Allowances to read the document. Big enough for 1, 3, 0, all pages.
72  const int kMemoryAllowances[] = {2000000, 4000000, 1000000, 100000000, 0};
73  // Order in which to read the pages, with some sequential and some seeks.
74  const int kPageReadOrder[] = {0, 1, 2, 3, 8, 4, 5, 6, 7, 11, 10, 9, -1};
75 
76  std::vector<std::string> page_texts;
77  std::string filename = MakeFakeDoc(kNumPages, 0, &page_texts);
78  // Now try getting it back with different memory allowances and check that
79  // the pages can still be read.
80  for (int m = 0; kMemoryAllowances[m] > 0; ++m) {
81  DocumentData read_doc("My document");
82  EXPECT_TRUE(
83  read_doc.LoadDocument(filename.c_str(), 0, kMemoryAllowances[m], nullptr));
84  LOG(ERROR) << "Allowance = " << kMemoryAllowances[m];
85  // Read the pages in a specific order.
86  for (int p = 0; kPageReadOrder[p] >= 0; ++p) {
87  int page = kPageReadOrder[p];
88  const ImageData* imagedata = read_doc.GetPage(page);
89  EXPECT_NE(nullptr, imagedata);
90  //EXPECT_NE(reinterpret_cast<ImageData*>(nullptr), imagedata);
91  // Check that this is the right page.
92  EXPECT_STREQ(page_texts[page].c_str(),
93  imagedata->transcription().c_str());
94  }
95  }
96 }
97 
98 TEST_F(ImagedataTest, CachesMultiDocs) {
99  // This test verifies that DocumentCache works to store multiple DocumentData
100  // and the two caching strategies read images in the right order.
101  // Number of pages in each document.
102  const std::vector<int> kNumPages = {6, 5, 7};
103  std::vector<std::vector<std::string>> page_texts;
104  GenericVector<STRING> filenames;
105  for (size_t d = 0; d < kNumPages.size(); ++d) {
106  page_texts.emplace_back(std::vector<std::string>());
107  std::string filename = MakeFakeDoc(kNumPages[d], d, &page_texts.back());
108  filenames.push_back(STRING(filename.c_str()));
109  }
110  // Now try getting them back with different cache strategies and check that
111  // the pages come out in the right order.
112  DocumentCache robin_cache(8000000);
113  robin_cache.LoadDocuments(filenames, tesseract::CS_ROUND_ROBIN, nullptr);
114  DocumentCache serial_cache(8000000);
115  serial_cache.LoadDocuments(filenames, tesseract::CS_SEQUENTIAL, nullptr);
116  for (int p = 0; p <= 21; ++p) {
117  LOG(INFO) << "Page " << p;
118  const ImageData* robin_data = robin_cache.GetPageBySerial(p);
119  const ImageData* serial_data = serial_cache.GetPageBySerial(p);
120  CHECK(robin_data != nullptr);
121  CHECK(serial_data != nullptr);
122  int robin_doc = p % kNumPages.size();
123  int robin_page = p / kNumPages.size() % kNumPages[robin_doc];
124  // Check that this is the right page.
125  EXPECT_STREQ(page_texts[robin_doc][robin_page].c_str(),
126  robin_data->transcription().c_str());
127  int serial_doc = p / kNumPages[0] % kNumPages.size();
128  int serial_page = p % kNumPages[0] % kNumPages[serial_doc];
129  EXPECT_STREQ(page_texts[serial_doc][serial_page].c_str(),
130  serial_data->transcription().c_str());
131  }
132 }
133 
134 } // namespace.
file::JoinPath
static std::string JoinPath(const std::string &s1, const std::string &s2)
Definition: include_gunit.h:43
string
std::string string
Definition: equationdetect_test.cc:21
INFO
Definition: log.h:29
tesseract::CS_ROUND_ROBIN
Definition: imagedata.h:53
STRING
Definition: strngs.h:45
tesseract::DocumentCache
Definition: imagedata.h:320
include_gunit.h
tesseract::TEST_F
TEST_F(EquationFinderTest, IdentifySpecialText)
Definition: equationdetect_test.cc:181
tesseract::CS_SEQUENTIAL
Definition: imagedata.h:48
ERROR
Definition: log.h:29
tesseract::ImageData
Definition: imagedata.h:104
GenericVector::push_back
int push_back(T object)
Definition: genericvector.h:799
CHECK
#define CHECK(test)
Definition: include_gunit.h:57
tesseract::ImageData::transcription
const STRING & transcription() const
Definition: imagedata.h:146
FLAGS_test_tmpdir
const char * FLAGS_test_tmpdir
Definition: include_gunit.h:20
STRING::c_str
const char * c_str() const
Definition: strngs.cpp:192
GenericVector< STRING >
imagedata.h
tesseract::ImageData::MemoryUsed
int MemoryUsed() const
Definition: imagedata.cpp:268
tesseract::DocumentData
Definition: imagedata.h:208
log.h
LOG
Definition: cleanapi_test.cc:19