OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
Mask.cpp
Go to the documentation of this file.
5 
6 #include <boost/regex.hpp>
7 #include <filesystem>
8 
9 namespace {
10  void updateCache(const std::vector<bool> &pixels, std::vector<int> &cache, int x, int width) {
11  const int height = cache.size();
12  for (int y = 0; y < height; ++ y) {
13  if (pixels[x + y * width]) {
14  ++ cache[y];
15  } else {
16  cache[y] = 0;
17  }
18  }
19  }
20 }
21 
22 namespace mslang {
23  long Mask::computeArea(const Mask::IntPoint &ll, const Mask::IntPoint &ur) const {
24  if ((ur.x_m > ll.x_m) && (ur.y_m > ll.y_m))
25  return (ur.x_m - ll.x_m) * (ur.y_m - ll.y_m);
26 
27  return 0;
28  }
29 
30  std::pair<Mask::IntPoint, Mask::IntPoint> Mask::findMaximalRectangle(const std::vector<bool> &pixels,
31  int M, /* height */
32  int N /* width */) const {
33 
34  // This algorithm was presented in
35  // http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529
36  // by David Vandevoorde, April 01, 1998
37 
38  int bestArea = 0;
39  IntPoint bestLL(0, 0), bestUR(0,0);
40  std::vector<int> cache(M, 0);
41  std::stack<std::pair<int, int> > stack;
42  for (int x = N - 1; x >= 0; -- x) {
43  updateCache(pixels, cache, x, N);
44  int width = 0;
45  for (int y = 0; y < M; ++ y) {
46  if (cache[y] > width) {
47  stack.push(std::make_pair(y, width));
48  width = cache[y];
49  } else if (cache[y] < width) {
50  int y0, w0;
51  do {
52  std::tie(y0, w0) = stack.top();
53  stack.pop();
54  if (width * (y - y0) > bestArea) {
55  bestLL.x_m = x; bestLL.y_m = y0;
56  bestUR.x_m = x + width; bestUR.y_m = y;
57  bestArea = width * (y - y0);
58  }
59  width = w0;
60  } while (!stack.empty() && cache[y] < width);
61  width = cache[y];
62  if (width != 0) {
63  stack.push(std::make_pair(y0, width));
64  }
65  }
66  }
67 
68  if (!stack.empty()) {
69  int y0, w0;
70  std::tie(y0, w0) = stack.top();
71  stack.pop();
72  if (width * (N - y0) > bestArea) {
73  bestLL.x_m = x; bestLL.y_m = y0;
74  bestUR.x_m = x + width; bestUR.y_m = N;
75  bestArea = width * (N - y0);
76  }
77  }
78  }
79 
80  return std::make_pair(bestLL, bestUR);
81  }
82 
83  std::vector<Mask::IntPixel_t> Mask::minimizeNumberOfRectangles(std::vector<bool> pixels,
84  int M,/* height */
85  int N /* width */)
86  {
87  std::vector<IntPixel_t> rectangles;
88 
89  long maxArea = 0;
90  while (true) {
91  IntPixel_t pix = findMaximalRectangle(pixels, M, N);
92  long area = computeArea(pix.first, pix.second);
93  if (area > maxArea) maxArea = area;
94  if (area <= 1) {
95  break;
96  }
97 
98  rectangles.push_back(pix);
99 
100  for (int y = pix.first.y_m; y < pix.second.y_m; ++ y) {
101  int idx = y * N + pix.first.x_m;
102  for (int x = pix.first.x_m; x < pix.second.x_m; ++ x, ++ idx) {
103  pixels[idx] = false;
104  }
105  }
106  }
107  int idx = 0;
108  for (int y = 0; y < M; ++ y) {
109  for (int x = 0; x < N; ++ x, ++idx) {
110  if (pixels[idx]) {
111  IntPoint ll(x, y);
112  IntPoint ur(x, y);
113  rectangles.push_back(IntPixel_t(ll, ur));
114  }
115  }
116  }
117 
118  return rectangles;
119  }
120 
122  Mask *pixmap = static_cast<Mask*>(fun);
123 
124  ArgumentExtractor arguments(std::string(it, end));
125  std::string filename = arguments.get(0);
126  if (filename[0] == '\'' && filename.back() == '\'') {
127  filename = filename.substr(1, filename.length() - 2);
128  }
129 
130  if (!std::filesystem::exists(filename)) {
131  ERRORMSG("file '" << filename << "' doesn't exists" << endl);
132  return false;
133  }
134 
135  PortableBitmapReader reader(filename);
136  int width = reader.getWidth();
137  int height = reader.getHeight();
138 
139  double pixel_width;
140  double pixel_height;
141  try {
142  pixel_width = parseMathExpression(arguments.get(1)) / width;
143  pixel_height = parseMathExpression(arguments.get(2)) / height;
144  } catch (std::runtime_error &e) {
145  std::cout << e.what() << std::endl;
146  return false;
147  }
148 
149  if (pixel_width < 0.0) {
150  std::cout << "Mask: a negative width provided '"
151  << arguments.get(0) << " = " << pixel_width * width << "'"
152  << std::endl;
153  return false;
154  }
155 
156  if (pixel_height < 0.0) {
157  std::cout << "Mask: a negative height provided '"
158  << arguments.get(1) << " = " << pixel_height * height << "'"
159  << std::endl;
160  return false;
161  }
162 
163  auto maxRect = pixmap->minimizeNumberOfRectangles(reader.getPixels(), height, width);
164  for (const IntPixel_t &pix: maxRect) {
165  const IntPoint &ll = pix.first;
166  const IntPoint &ur = pix.second;
167 
168  Rectangle rect;
169  rect.width_m = (ur.x_m - ll.x_m) * pixel_width;
170  rect.height_m = (ur.y_m - ll.y_m) * pixel_height;
171 
172  double midX = 0.5 * (ur.x_m + ll.x_m);
173  double midY = 0.5 * (ur.y_m + ll.y_m);
174  rect.trafo_m = AffineTransformation(Vector_t(1, 0, (0.5 * width - midX) * pixel_width),
175  Vector_t(0, 1, (midY - 0.5 * height) * pixel_height));
176 
177  pixmap->pixels_m.push_back(rect);
178  pixmap->pixels_m.back().computeBoundingBox();
179  }
180 
181  it += (arguments.getLengthConsumed() + 1);
182 
183  return true;
184  }
185 
186  void Mask::print(int ident) {
187  for (auto pix: pixels_m) pix.print(ident);
188  }
189 
190  void Mask::apply(std::vector<std::shared_ptr<Base> > &bfuncs) {
191  for (auto pix: pixels_m) pix.apply(bfuncs);
192  }
193 }
unsigned int getHeight() const
AffineTransformation trafo_m
Definition: MSLang.h:40
and that you know you can do these things To protect your we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights These restrictions translate to certain responsibilities for you if you distribute copies of the or if you modify it For if you distribute copies of such a whether gratis or for a you must give the recipients all the rights that you have You must make sure that receive or can get the source code And you must show them these terms so they know their rights We protect your rights with two distribute and or modify the software for each author s protection and we want to make certain that everyone understands that there is no warranty for this free software If the software is modified by someone else and passed we want its recipients to know that what they have is not the so that any problems introduced by others will not reflect on the original authors reputations any free program is threatened constantly by software patents We wish to avoid the danger that redistributors of a free program will individually obtain patent in effect making the program proprietary To prevent we have made it clear that any patent must be licensed for everyone s free use or not licensed at all The precise terms and conditions for distribution and modification follow GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR DISTRIBUTION AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License The refers to any such program or and a work based on the Program means either the Program or any derivative work under copyright a work containing the Program or a portion of it
Definition: LICENSE:43
std::pair< IntPoint, IntPoint > findMaximalRectangle(const std::vector< bool > &pixels, int height, int width) const
Definition: Mask.cpp:30
double parseMathExpression(const std::string &str)
Definition: matheval.cpp:4
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
std::pair< IntPoint, IntPoint > IntPixel_t
Definition: Mask.h:27
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
unsigned int getWidth() const
double width_m
Definition: Rectangle.h:8
std::vector< Rectangle > pixels_m
Definition: Mask.h:13
std::string::iterator iterator
Definition: MSLang.h:15
static bool parse_detail(iterator &it, const iterator &end, Function *&fun)
Definition: Mask.cpp:121
unsigned int getLengthConsumed() const
std::vector< IntPixel_t > minimizeNumberOfRectangles(std::vector< bool > pixels, int height, int width)
Definition: Mask.cpp:83
std::string get(unsigned int i) const
long computeArea(const IntPoint &ll, const IntPoint &ur) const
Definition: Mask.cpp:23
virtual void print(int ident)
Definition: Mask.cpp:186
double height_m
Definition: Rectangle.h:9
std::vector< bool > getPixels() const
virtual void apply(std::vector< std::shared_ptr< Base > > &bfuncs)
Definition: Mask.cpp:190
constexpr double e
The value of .
Definition: Physics.h:39
end
Definition: multipole_t.tex:9