Code indexing in gitaly is broken and leads to code not being visible to the user. We work on the issue with highest priority.

Skip to content
Snippets Groups Projects
Commit 6ac091fc authored by adelmann's avatar adelmann :reminder_ribbon:
Browse files

Merge branch '775-masks' into 'master'

Resolve "Masks"

Closes #775

See merge request OPAL/src!633
parents 1cce4b61 dc606c8a
No related branches found
No related tags found
No related merge requests found
...@@ -6,20 +6,21 @@ ...@@ -6,20 +6,21 @@
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
namespace mslang { namespace {
void Mask::updateCache(const std::vector<bool> &pixels, std::vector<unsigned int> &cache, unsigned int y) const { void updateCache(const std::vector<bool> &pixels, std::vector<int> &cache, int x, int width) {
const unsigned int M = cache.size(); const int height = cache.size();
unsigned int idx = y * M; for (int y = 0; y < height; ++ y) {
for (unsigned int x = 0; x < M; ++ x, ++ idx) { if (pixels[x + y * width]) {
if (pixels[idx]) { ++ cache[y];
++ cache[x];
} else { } else {
cache[x] = 0; cache[y] = 0;
} }
} }
} }
}
unsigned int Mask::computeArea(const Mask::IntPoint &ll, const Mask::IntPoint &ur) const { namespace mslang {
long Mask::computeArea(const Mask::IntPoint &ll, const Mask::IntPoint &ur) const {
if ((ur.x_m > ll.x_m) && (ur.y_m > ll.y_m)) if ((ur.x_m > ll.x_m) && (ur.y_m > ll.y_m))
return (ur.x_m - ll.x_m) * (ur.y_m - ll.y_m); return (ur.x_m - ll.x_m) * (ur.y_m - ll.y_m);
...@@ -27,50 +28,51 @@ namespace mslang { ...@@ -27,50 +28,51 @@ namespace mslang {
} }
std::pair<Mask::IntPoint, Mask::IntPoint> Mask::findMaximalRectangle(const std::vector<bool> &pixels, std::pair<Mask::IntPoint, Mask::IntPoint> Mask::findMaximalRectangle(const std::vector<bool> &pixels,
unsigned int N, /* height */ int M, /* height */
unsigned int M /* width */) const { int N /* width */) const {
// This algorithm was presented in // This algorithm was presented in
// http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529 // http://www.drdobbs.com/database/the-maximal-rectangle-problem/184410529
// by David Vandevoorde, April 01, 1998 // by David Vandevoorde, April 01, 1998
unsigned int bestArea = 0; int bestArea = 0;
IntPoint bestLL(0, 0), bestUR(0,0); IntPoint bestLL(0, 0), bestUR(0,0);
std::vector<unsigned int> cache(M, 0); std::vector<int> cache(M, 0);
std::stack<std::pair<unsigned int, unsigned int> > stack; std::stack<std::pair<int, int> > stack;
for (unsigned int y = N - 1; y + 1 > 0; -- y) { for (int x = N - 1; x >= 0; -- x) {
updateCache(pixels, cache, y); updateCache(pixels, cache, x, N);
unsigned int height = 0; int width = 0;
for (unsigned int x = 0; x < M; ++ x) { for (int y = 0; y < M; ++ y) {
if (cache[x] > height) { if (cache[y] > width) {
stack.push(std::make_pair(x, height)); stack.push(std::make_pair(y, width));
height = cache[x]; width = cache[y];
} else if (cache[x] < height) { } else if (cache[y] < width) {
std::pair<unsigned int, unsigned int> tmp; int y0, w0;
do { do {
tmp = stack.top(); std::tie(y0, w0) = stack.top();
stack.pop(); stack.pop();
if (x > tmp.first && height * (x - tmp.first) > bestArea) { if (width * (y - y0) > bestArea) {
bestLL.x_m = tmp.first; bestLL.y_m = y; bestLL.x_m = x; bestLL.y_m = y0;
bestUR.x_m = x; bestUR.y_m = y + height; bestUR.x_m = x + width; bestUR.y_m = y;
bestArea = height * (x - tmp.first); bestArea = width * (y - y0);
} }
height = tmp.second; width = w0;
} while (!stack.empty() && cache[x] < height); } while (!stack.empty() && cache[y] < width);
height = cache[x]; width = cache[y];
if (height != 0) { if (width != 0) {
stack.push(std::make_pair(tmp.first, height)); stack.push(std::make_pair(y0, width));
} }
} }
} }
if (!stack.empty()) { if (!stack.empty()) {
std::pair<unsigned int, unsigned int> tmp = stack.top(); int y0, w0;
std::tie(y0, w0) = stack.top();
stack.pop(); stack.pop();
if (M > tmp.first && height * (M - tmp.first) > bestArea) { if (width * (N - y0) > bestArea) {
bestLL.x_m = tmp.first; bestLL.y_m = y; bestLL.x_m = x; bestLL.y_m = y0;
bestUR.x_m = M; bestUR.y_m = y + height; bestUR.x_m = x + width; bestUR.y_m = N;
bestArea = height * (M - tmp.first); bestArea = width * (N - y0);
} }
} }
} }
...@@ -79,36 +81,35 @@ namespace mslang { ...@@ -79,36 +81,35 @@ namespace mslang {
} }
std::vector<Mask::IntPixel_t> Mask::minimizeNumberOfRectangles(std::vector<bool> pixels, std::vector<Mask::IntPixel_t> Mask::minimizeNumberOfRectangles(std::vector<bool> pixels,
unsigned int N,/* height */ int M,/* height */
unsigned int M /* width */) int N /* width */)
{ {
std::vector<IntPixel_t> rectangles; std::vector<IntPixel_t> rectangles;
unsigned int maxArea = 0; long maxArea = 0;
while (true) { while (true) {
IntPixel_t pix = findMaximalRectangle(pixels, N, M); IntPixel_t pix = findMaximalRectangle(pixels, M, N);
unsigned int area = computeArea(pix.first, pix.second); long area = computeArea(pix.first, pix.second);
if (area > maxArea) maxArea = area; if (area > maxArea) maxArea = area;
if (1000 * area < maxArea || area <= 1) { if (area <= 1) {
break; break;
} }
rectangles.push_back(pix); rectangles.push_back(pix);
for (int y = pix.first.y_m; y < pix.second.y_m; ++ y) { for (int y = pix.first.y_m; y < pix.second.y_m; ++ y) {
unsigned int idx = y * M + pix.first.x_m; int idx = y * N + pix.first.x_m;
for (int x = pix.first.x_m; x < pix.second.x_m; ++ x, ++ idx) { for (int x = pix.first.x_m; x < pix.second.x_m; ++ x, ++ idx) {
pixels[idx] = false; pixels[idx] = false;
} }
} }
} }
int idx = 0;
unsigned int idx = 0; for (int y = 0; y < M; ++ y) {
for (unsigned int y = 0; y < N; ++ y) { for (int x = 0; x < N; ++ x, ++idx) {
for (unsigned int x = 0; x < M; ++ x, ++idx) {
if (pixels[idx]) { if (pixels[idx]) {
IntPoint ll(x, y); IntPoint ll(x, y);
IntPoint ur(x + 1, y + 1); IntPoint ur(x, y);
rectangles.push_back(IntPixel_t(ll, ur)); rectangles.push_back(IntPixel_t(ll, ur));
} }
} }
...@@ -132,8 +133,8 @@ namespace mslang { ...@@ -132,8 +133,8 @@ namespace mslang {
} }
PortableBitmapReader reader(filename); PortableBitmapReader reader(filename);
unsigned int width = reader.getWidth(); int width = reader.getWidth();
unsigned int height = reader.getHeight(); int height = reader.getHeight();
double pixel_width; double pixel_width;
double pixel_height; double pixel_height;
...@@ -160,7 +161,6 @@ namespace mslang { ...@@ -160,7 +161,6 @@ namespace mslang {
} }
auto maxRect = pixmap->minimizeNumberOfRectangles(reader.getPixels(), height, width); auto maxRect = pixmap->minimizeNumberOfRectangles(reader.getPixels(), height, width);
for (const IntPixel_t &pix: maxRect) { for (const IntPixel_t &pix: maxRect) {
const IntPoint &ll = pix.first; const IntPoint &ll = pix.first;
const IntPoint &ur = pix.second; const IntPoint &ur = pix.second;
......
...@@ -27,16 +27,14 @@ namespace mslang { ...@@ -27,16 +27,14 @@ namespace mslang {
typedef std::pair<IntPoint, IntPoint> IntPixel_t; typedef std::pair<IntPoint, IntPoint> IntPixel_t;
std::vector<IntPixel_t> minimizeNumberOfRectangles(std::vector<bool> pixels, std::vector<IntPixel_t> minimizeNumberOfRectangles(std::vector<bool> pixels,
unsigned int height, int height,
unsigned int width); int width);
std::pair<IntPoint, IntPoint> findMaximalRectangle(const std::vector<bool> &pixels, std::pair<IntPoint, IntPoint> findMaximalRectangle(const std::vector<bool> &pixels,
unsigned int height, int height,
unsigned int width) const; int width) const;
unsigned int computeArea(const IntPoint &ll, const IntPoint &ur) const; long computeArea(const IntPoint &ll, const IntPoint &ur) const;
void updateCache(const std::vector<bool> &pixels, std::vector<unsigned int> &cache, unsigned int y) const;
}; };
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment