contrek 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -3
  3. data/CHANGELOG.md +21 -0
  4. data/Gemfile.lock +4 -4
  5. data/README.md +34 -30
  6. data/Rakefile +3 -0
  7. data/contrek.gemspec +7 -4
  8. data/ext/cpp_polygon_finder/PolygonFinder/Makefile +44 -0
  9. data/ext/cpp_polygon_finder/PolygonFinder/images/sample_10240x10240.png +0 -0
  10. data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +14 -5
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +136 -15
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +5 -4
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/CpuTimer.h +44 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +8 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +3 -4
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +63 -573
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +17 -18
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +22 -5
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +4 -8
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.c +6980 -0
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.h +537 -0
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp +101 -0
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.h +16 -0
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +0 -3
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +4 -7
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +13 -13
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +5 -7
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +47 -41
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +15 -10
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +181 -178
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +19 -20
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +20 -0
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +52 -137
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +85 -16
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/RectBounds.h +39 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.cpp +14 -0
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ClippedPolygonFinder.h +17 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +117 -0
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +32 -0
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +344 -0
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.h +46 -0
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.cpp +14 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +22 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.cpp +13 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/FakeCluster.h +17 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +138 -0
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +52 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.cpp +23 -0
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Hub.h +40 -0
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +70 -0
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +47 -0
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.cpp +24 -0
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/PartPool.h +23 -0
  54. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +182 -0
  55. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.h +30 -0
  56. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +108 -0
  57. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +52 -0
  58. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.cpp +59 -0
  59. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Poolable.h +52 -0
  60. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +31 -0
  61. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +25 -0
  62. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queue.h +36 -0
  63. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +230 -0
  64. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +35 -0
  65. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +20 -0
  66. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +26 -0
  67. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +23 -0
  68. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +105 -0
  69. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +56 -0
  70. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +3 -3
  71. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +5 -8
  72. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +3 -7
  73. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +2 -2
  74. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +4 -8
  75. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +2 -2
  76. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +3 -7
  77. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +23 -15
  78. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +6 -8
  79. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +2 -5
  80. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +4 -8
  81. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +9 -12
  82. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +3 -7
  83. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +26 -27
  84. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +76 -87
  85. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +64 -32
  86. data/ext/cpp_polygon_finder/extconf.rb +14 -0
  87. data/lib/contrek/bitmaps/sample_generator.rb +56 -0
  88. data/lib/contrek/cpp/cpp_concurrent_finder.rb +9 -0
  89. data/lib/contrek/finder/bounds.rb +17 -0
  90. data/lib/contrek/finder/concurrent/cluster.rb +2 -2
  91. data/lib/contrek/finder/concurrent/cursor.rb +8 -8
  92. data/lib/contrek/finder/concurrent/finder.rb +10 -9
  93. data/lib/contrek/finder/concurrent/part.rb +2 -2
  94. data/lib/contrek/finder/concurrent/partitionable.rb +1 -1
  95. data/lib/contrek/finder/concurrent/polyline.rb +17 -15
  96. data/lib/contrek/finder/concurrent/sequence.rb +11 -0
  97. data/lib/contrek/finder/concurrent/tile.rb +3 -3
  98. data/lib/contrek/finder/node_cluster.rb +16 -8
  99. data/lib/contrek/finder/polygon_finder.rb +1 -4
  100. data/lib/contrek/version.rb +1 -1
  101. data/lib/contrek.rb +9 -1
  102. metadata +62 -15
  103. data/ext/cpp_polygon_finder/PolygonFinder/.cproject +0 -136
  104. data/ext/cpp_polygon_finder/PolygonFinder/.project +0 -27
  105. data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +0 -2
  106. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +0 -48
  107. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +0 -32
@@ -6,198 +6,113 @@
6
6
  * Copyright 2025 Emanuele Cesaroni
7
7
  */
8
8
 
9
-
10
9
  #include <iostream>
11
10
  #include <list>
12
11
  #include <map>
13
12
  #include <ctime>
14
13
  #include <typeinfo>
15
14
  #include <string>
16
- #include <ctime>
17
15
  #include <vector>
16
+ #include <utility>
18
17
  #include "PolygonFinder.h"
19
18
  #include "../bitmaps/Bitmap.h"
20
19
  #include "../matchers/Matcher.h"
21
20
  #include "../matchers/RGBMatcher.h"
21
+ #include "../matchers/RGBNotMatcher.h"
22
22
  #include "optionparser.h"
23
23
  #include "NodeCluster.h"
24
24
  #include "Node.h"
25
-
26
- PolygonFinder::PolygonFinder(Bitmap *bitmap, Matcher *matcher, Bitmap *test_bitmap, std::vector<std::string> *options) {
27
- source_bitmap = bitmap;
28
- this->matcher = matcher;
29
- if (options != nullptr) sanitize_options(options);
30
- this->node_cluster = new NodeCluster(source_bitmap->h(), &this->options);
25
+ #include "FinderUtils.h"
26
+
27
+ PolygonFinder::PolygonFinder(Bitmap *bitmap,
28
+ Matcher *matcher,
29
+ Bitmap *test_bitmap,
30
+ std::vector<std::string> *options,
31
+ int start_x,
32
+ int end_x)
33
+ : source_bitmap(bitmap),
34
+ matcher(matcher),
35
+ start_x(start_x),
36
+ end_x(end_x == -1 ? bitmap->w() : end_x)
37
+ { this->rgb_matcher = dynamic_cast<RGBMatcher*>(matcher);
38
+ if (options != nullptr) FinderUtils::sanitize_options(this->options, options);
39
+ this->node_cluster = new NodeCluster(source_bitmap->h(), source_bitmap->w(), &this->options);
31
40
 
32
41
  //= SCAN ==============//
33
- start_timer();
42
+ cpu_timer.start();
34
43
  scan();
35
- reports["scan"] = end_timer();
44
+ reports["scan"] = cpu_timer.stop();
36
45
  //=====================//
37
46
 
38
47
  //= BUILD_TANGS_SEQUENCE ===//
39
- start_timer();
48
+ cpu_timer.start();
40
49
  node_cluster->build_tangs_sequence();
41
- reports["build_tangs_sequence"] = end_timer();
50
+ reports["build_tangs_sequence"] = cpu_timer.stop();
42
51
  //=====================//
43
52
 
44
53
  //= PLOT ===//
45
- start_timer();
54
+ cpu_timer.start();
46
55
  node_cluster->plot(this->options.versus);
47
- reports["plot"] = end_timer();
56
+ reports["plot"] = cpu_timer.stop();
48
57
  //=====================//
49
58
 
50
59
  //= COMPRESS_COORDS ===//
51
- start_timer();
52
- node_cluster->compress_coords(this->options);
53
- reports["compress"] = end_timer();
60
+ cpu_timer.start();
61
+ node_cluster->compress_coords(this->node_cluster->polygons, this->options);
62
+ reports["compress"] = cpu_timer.stop();
54
63
  //=====================//
55
64
  reports["total"] = reports["scan"] + reports["build_tangs_sequence"] + reports["plot"] + reports["compress"];
56
65
  }
57
66
 
58
67
  std::list<ShapeLine*> *PolygonFinder::get_shapelines() {
59
68
  std::list<ShapeLine*> *sll = new std::list<ShapeLine*>();
60
- for (int line = 0; line < this->node_cluster->height; line++)
61
- { for (std::vector<Node*>::iterator node = this->node_cluster->vert_nodes[line].begin(); node != this->node_cluster->vert_nodes[line].end(); ++node)
62
- { ShapeLine *sl = new ShapeLine({(*node)->min_x, (*node)->max_x, (*node)->y});
69
+ for (int line = 0; line < this->node_cluster->height; line++) {
70
+ for (Node& node : this->node_cluster->vert_nodes[line]) {
71
+ ShapeLine *sl = new ShapeLine({node.min_x, node.max_x, node.y});
63
72
  sll->push_back(sl);
64
73
  }
65
74
  }
66
- return(sll);
67
- }
68
-
69
- void PolygonFinder::sanitize_options(std::vector<std::string> *incoming_options)
70
- { std::vector<char*> argv0;
71
- for (const auto& arg : *incoming_options)
72
- argv0.push_back((char*)arg.data());
73
- argv0.push_back(nullptr);
74
- char** argv = &argv0[0];
75
- int argc = argv0.size() -1;
76
-
77
- enum optionIndex { COMPRESS_UNIQ, VERSUS, COMPRESS_VISVALINGAM, COMPRESS_LINEAR, COMPRESS_VISVALINGAM_TOLERANCE, TREEMAP};
78
- const option::Descriptor usage[] = {
79
- // {UNKNOWN, 0,"" , "" ,option::Arg::None, 0},
80
- {COMPRESS_VISVALINGAM, 0, "" , "compress_visvalingam", option::Arg::None, 0},
81
- {COMPRESS_LINEAR, 0, "" , "compress_linear", option::Arg::None, 0},
82
- {COMPRESS_VISVALINGAM_TOLERANCE, 0, "" , "compress_visvalingam_tolerance", option::Arg::Optional, 0},
83
- {COMPRESS_UNIQ, 0, "", "compress_uniq", option::Arg::None, 0},
84
- {TREEMAP, 0, "", "treemap", option::Arg::None, 0},
85
- {VERSUS, 0, "v", "versus", option::Arg::Optional, 0},
86
- {0, 0, 0, 0, 0, 0}
87
- };
88
-
89
- option::Stats stats(usage, argc, argv);
90
- option::Option ioptions[stats.options_max], buffer[stats.buffer_max];
91
- option::Parser parse(usage, argc, argv, ioptions, buffer);
92
-
93
- if (parse.error()) return;
94
- // VERSUS
95
- if (ioptions[VERSUS].count() > 0)
96
- { for (option::Option* opt = ioptions[VERSUS]; opt; opt = opt->next())
97
- { std::string opts = opt->arg;
98
- this->options.versus = (opts.compare("a") == 0 ? Node::A : Node::O);
99
- break;
100
- }
101
- }
102
- // COMPRESS UNIQ
103
- if (ioptions[COMPRESS_UNIQ].count() > 0)
104
- { this->options.compress_uniq = true;
105
- }
106
- // TREEMAP
107
- if (ioptions[TREEMAP].count() > 0)
108
- { this->options.treemap = true;
109
- }
110
- // COMPRESS LINEAR
111
- if (ioptions[COMPRESS_LINEAR].count() > 0)
112
- { this->options.compress_linear = true;
113
- }
114
- // COMPRESS UNIQ
115
- if (ioptions[COMPRESS_VISVALINGAM].count() > 0)
116
- { this->options.compress_visvalingam = true;
117
- }
118
- if (ioptions[COMPRESS_VISVALINGAM_TOLERANCE].count() > 0)
119
- { this->options.compress_visvalingam = true;
120
- for (option::Option* opt = ioptions[COMPRESS_VISVALINGAM_TOLERANCE]; opt; opt = opt->next())
121
- { std::string opts = opt->arg;
122
- this->options.compress_visvalingam_tolerance = strtof(opt->arg, 0);
123
- break;
124
- }
125
- }
126
- /*std::cout << "-----------" << std::endl;
127
- std::cout << "versus" << this->options.versus << std::endl;
128
- std::cout << "uniq" << this->options.compress_uniq << std::endl;
129
- std::cout << "linear" << this->options.compress_linear << std::endl;
130
- std::cout << "visvalingam" << this->options.compress_visvalingam << std::endl;
131
- std::cout << this->options.compress_visvalingam_tolerance << std::endl;
132
- std::cout << "-----------" << std::endl;*/
133
- }
134
-
135
- void PolygonFinder::start_timer() {
136
- timer_start = std::clock();
137
- }
138
-
139
- double PolygonFinder::end_timer() {
140
- std::clock_t c_end = std::clock();
141
- return 1000.0 * (c_end - timer_start) / CLOCKS_PER_SEC;
75
+ return sll;
142
76
  }
143
77
 
144
78
  PolygonFinder::~PolygonFinder() {
79
+ delete this->node_cluster;
145
80
  }
146
81
 
147
82
  void PolygonFinder::scan() {
148
- char last_color = 0, color = 0;
149
- int min_x = 0;
150
- int max_x = 0;
151
- bool match;
152
- bool matching = false;
153
-
154
- for (int y = 0; y < this->source_bitmap->h(); y++)
155
- { for (int x = 0; x < this->source_bitmap->w(); x++)
156
- { color = this->source_bitmap->value_at(x, y);
157
- match = this->source_bitmap->pixel_match(x, y, this->matcher);
158
- if (match && matching == false)
159
- { min_x = x;
160
- last_color = color;
161
- matching = true;
162
- if (x == (this->source_bitmap->w() - 1) )
163
- { max_x = x;
164
- this->node_cluster->add_node(new Node(min_x, max_x, y, last_color));
165
- matching = false;
166
- }
167
- } else {
168
- if (!match && matching == true)
169
- { max_x = x - 1;
170
- this->node_cluster->add_node(new Node(min_x, max_x, y, last_color));
171
- matching = false;
172
- } else {
173
- if (x == (this->source_bitmap->w()-1) && matching == true)
174
- { max_x = x;
175
- this->node_cluster->add_node(new Node(min_x, max_x, y, last_color));
176
- matching = false;
177
- }
178
- }
179
- }
83
+ int bpp = this->source_bitmap->get_bytes_per_pixel();
84
+
85
+ RGBMatcher* rgb_m = dynamic_cast<RGBMatcher*>(this->matcher);
86
+
87
+ if (bpp == 1) {
88
+ auto fetcher = [](const unsigned char* p) { return static_cast<unsigned int>(p[0]); };
89
+ if (rgb_m) run_loop(rgb_m, fetcher);
90
+ else run_loop(this->matcher, fetcher);
91
+ } else {
92
+ auto fetcher = [](const unsigned char* p) { return p[0] | (p[1] << 8) | (p[2] << 16); };
93
+ if (rgb_m) run_loop(rgb_m, fetcher);
94
+ else run_loop(this->matcher, fetcher);
180
95
  }
181
- }
182
96
  }
183
97
 
184
98
  ProcessResult* PolygonFinder::process_info() {
185
99
  ProcessResult *pr = new ProcessResult();
186
- pr->groups = this->node_cluster->sequences->size();
187
- pr->polygons = this->node_cluster->polygons;
188
- pr->benchmarks = this->reports;
100
+ pr->groups = this->node_cluster->sequences.size();
101
+ pr->polygons = std::move(this->node_cluster->polygons);
102
+ pr->benchmarks = std::move(this->reports);
189
103
  pr->treemap = this->node_cluster->treemap;
190
104
 
191
- if (typeid(*this->source_bitmap) == typeid(Bitmap))
105
+ if (this->node_cluster->options->named_sequences && typeid(*this->source_bitmap) == typeid(Bitmap))
192
106
  { std::string sequence;
193
107
  int n = 0;
194
- for (std::list<std::list<Node*>*>::iterator list = this->node_cluster->sequences->begin(); list != this->node_cluster->sequences->end(); ++list, n++)
195
- { std::string seq;
196
- for (std::list<Node*>::iterator node = (*list)->begin(); node != (*list)->end(); ++node)
197
- { seq += (*node)->name;
108
+ for (const auto& seq_list : this->node_cluster->sequences) {
109
+ std::string seq;
110
+ for (Node* node : seq_list) {
111
+ seq += node->name;
198
112
  }
199
113
  if (n != 0) sequence += '-';
200
114
  sequence += seq;
115
+ n++;
201
116
  }
202
117
  pr->named_sequence = sequence;
203
118
  }
@@ -6,15 +6,20 @@
6
6
  * Copyright 2025 Emanuele Cesaroni
7
7
  */
8
8
 
9
- #ifndef POLYGONFINDER_H_
10
- #define POLYGONFINDER_H_
11
-
9
+ #pragma once
12
10
  #include <list>
13
11
  #include <vector>
14
- #include "Node.h"
15
12
  #include <ctime>
16
13
  #include <string>
17
14
  #include <map>
15
+ #include <iostream>
16
+ #include <utility>
17
+ #include "../bitmaps/Bitmap.h"
18
+ #include "NodeCluster.h"
19
+ #include "Node.h"
20
+ #include "Polygon.h"
21
+ #include "Node.h"
22
+ #include "../CpuTimer.h"
18
23
 
19
24
  class Bitmap;
20
25
  class Matcher;
@@ -33,37 +38,101 @@ struct pf_Options {
33
38
  bool compress_uniq = false;
34
39
  bool compress_linear = false;
35
40
  bool compress_visvalingam = false;
41
+ bool named_sequences = false;
42
+ bool bounds = false;
36
43
  float compress_visvalingam_tolerance = 10.0;
44
+ int number_of_tiles = 1;
45
+ std::string get_alpha_versus() {
46
+ return(versus == Node::A ? "a" : "o");
47
+ }
37
48
  };
38
49
  struct ProcessResult {
39
50
  int groups;
40
51
  std::map<std::string, double> benchmarks;
41
- std::list<std::map<std::string, std::list<std::list<Point*>*>>> polygons;
52
+ std::list<Polygon> polygons;
42
53
  std::string named_sequence;
43
- std::list<int*> treemap;
54
+ std::vector<std::pair<int, int>> treemap;
55
+
56
+ void print_polygons() {
57
+ int counter = 0;
58
+ for (const auto& polygon : polygons) {
59
+ std::cout << counter << " - " << "outer" << "\n";
60
+ for (const Point* p : polygon.outer) std::cout << p->toString();
61
+ bool first = true;
62
+ for (const auto& seq : polygon.inner) {
63
+ if (!first) std::cout << "\n";
64
+ first = false;
65
+ for (const Point* p : seq) std::cout << p->toString();
66
+ }
67
+ std::cout << "\n";
68
+ counter++;
69
+ }
70
+ }
71
+
72
+ void print_info() {
73
+ for (const auto& [key, value] : benchmarks) {
74
+ std::cout << key << ": " << value << ", ";
75
+ }
76
+ std::cout << std::endl;
77
+ }
44
78
  };
45
79
 
46
80
  class PolygonFinder {
81
+ protected:
82
+ int start_x;
83
+ int end_x;
84
+
47
85
  private:
48
86
  Bitmap *source_bitmap;
49
87
  Matcher *matcher;
88
+ RGBMatcher* rgb_matcher;
50
89
  NodeCluster *node_cluster;
51
90
  pf_Options options;
52
91
  std::map<std::string, double> reports;
53
- void start_timer();
54
- double end_timer();
55
92
  void scan();
56
- std::clock_t timer_start, timer_end;
57
- void sanitize_options(std::vector<std::string> *incoming_options);
93
+ CpuTimer cpu_timer;
94
+
95
+ template <typename M, typename F>
96
+ void run_loop(M* specific_matcher, F&& fetch_color) {
97
+ int img_h = this->source_bitmap->h();
98
+ int bpp = this->source_bitmap->get_bytes_per_pixel();
99
+ for (int y = 0; y < img_h; y++) {
100
+ const unsigned char* row_ptr = this->source_bitmap->get_row_ptr(y);
101
+ const unsigned char* p = row_ptr + (this->start_x * bpp);
102
+ int min_x = 0;
103
+ bool matching = false;
104
+ unsigned char last_red_value = 0;
105
+ for (int x = this->start_x; x < this->end_x; x++) {
106
+ unsigned int color = fetch_color(p);
107
+ unsigned char current_val = p[0];
108
+ p += bpp;
109
+ if (specific_matcher->match(color)) {
110
+ if (!matching) {
111
+ min_x = x;
112
+ last_red_value = current_val;
113
+ matching = true;
114
+ }
115
+ if (x == this->end_x - 1) {
116
+ this->node_cluster->add_node(min_x, x, y, last_red_value);
117
+ matching = false;
118
+ }
119
+ } else if (matching) {
120
+ this->node_cluster->add_node(min_x, x - 1, y, last_red_value);
121
+ matching = false;
122
+ }
123
+ }
124
+ }
125
+ }
58
126
 
59
127
  public:
60
- PolygonFinder(Bitmap *bitmap, Matcher *matcher, Bitmap *test_bitmap, std::vector<std::string> *options = nullptr);
128
+ PolygonFinder(Bitmap *bitmap,
129
+ Matcher *matcher,
130
+ Bitmap *test_bitmap,
131
+ std::vector<std::string> *options = nullptr,
132
+ int start_x = 0,
133
+ int end_x = -1);
61
134
  ProcessResult* process_info();
62
135
  std::list<ShapeLine*> *get_shapelines();
63
136
  virtual ~PolygonFinder();
137
+ const NodeCluster* get_cluster() const { return this->node_cluster; }
64
138
  };
65
-
66
-
67
-
68
-
69
- #endif /* POLYGONFINDER_H_ */
@@ -0,0 +1,39 @@
1
+ /*
2
+ * RectBounds.h
3
+ *
4
+ * Created on: 23 nov 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #pragma once
10
+ #include <limits>
11
+ #include <algorithm>
12
+
13
+ struct RectBounds {
14
+ int min_x = std::numeric_limits<int>::max();
15
+ int max_x = std::numeric_limits<int>::min();
16
+ int min_y = std::numeric_limits<int>::max();
17
+ int max_y = std::numeric_limits<int>::min();
18
+
19
+ static RectBounds empty() {
20
+ return RectBounds{};
21
+ }
22
+
23
+ inline RectBounds& expand(int x, int y) {
24
+ if (x < min_x) min_x = x;
25
+ if (x > max_x) max_x = x;
26
+ if (y < min_y) min_y = y;
27
+ if (y > max_y) max_y = y;
28
+ return *this;
29
+ }
30
+
31
+ inline bool is_empty() const {
32
+ return min_x == std::numeric_limits<int>::max();
33
+ }
34
+
35
+ inline int width() const {
36
+ if (is_empty()) return 0;
37
+ return(max_x - min_x);
38
+ }
39
+ };
@@ -0,0 +1,14 @@
1
+ /*
2
+ * ClippedPolygonFinder.cpp
3
+ *
4
+ * Created on: 23 nov 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+ #include <string>
9
+ #include <vector>
10
+ #include "ClippedPolygonFinder.h"
11
+
12
+ ClippedPolygonFinder::ClippedPolygonFinder(Bitmap *bitmap, Matcher *matcher, int bitmap_start_x, int bitmap_end_x, std::vector<std::string> *options)
13
+ : PolygonFinder(bitmap, matcher, nullptr, options, bitmap_start_x, bitmap_end_x) {
14
+ }
@@ -0,0 +1,17 @@
1
+ /*
2
+ * ClippedPolygonFinder.h
3
+ *
4
+ * Created on: 23 nov 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #pragma once
10
+ #include <string>
11
+ #include <vector>
12
+ #include "../PolygonFinder.h"
13
+
14
+ class ClippedPolygonFinder : public PolygonFinder {
15
+ public:
16
+ ClippedPolygonFinder(Bitmap *bitmap, Matcher *matcher, int bm_start_x, int bm_end_x, std::vector<std::string> *options = nullptr);
17
+ };
@@ -0,0 +1,117 @@
1
+ /*
2
+ * Cluster.cpp
3
+ *
4
+ * Created on: 23 nov 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #include <vector>
10
+ #include <list>
11
+ #include <iostream>
12
+ #include "Cluster.h"
13
+ #include "Shape.h"
14
+ #include "Polyline.h"
15
+ #include "Sequence.h"
16
+ #include "Cursor.h"
17
+ #include "../../CpuTimer.h"
18
+
19
+ Cluster::Cluster(Finder *finder, int height, int width)
20
+ : finder(finder)
21
+ { tiles_.reserve(2); // only two (left|right)
22
+ this->hub_ = new Hub(height, width);
23
+ }
24
+
25
+ Cluster::~Cluster() {
26
+ for (Tile* tile : tiles_) {
27
+ delete tile;
28
+ }
29
+ delete this->hub_;
30
+ }
31
+
32
+ void Cluster::add(Tile* tile) {
33
+ Tile* last_tile = tiles_.empty() ? nullptr : tiles_.back();
34
+ tiles_.push_back(tile);
35
+ tile->cluster = this;
36
+ if (last_tile) {
37
+ last_tile->next = last_tile->circular_next = tile;
38
+ tile->prev = tile->circular_next = last_tile;
39
+ }
40
+ }
41
+
42
+ void Cluster::list_to_string(std::vector<Point*> list)
43
+ { std::cout << "(" << &list << ") ";
44
+ for (Point* point : list) {
45
+ std::cout << point->toString();
46
+ }
47
+ std::cout << std::endl;
48
+ }
49
+
50
+ Tile* Cluster::merge_tiles() {
51
+ double tot_inner = 0;
52
+ double tot_outer = 0;
53
+ CpuTimer timer;
54
+ std::list<Shape*> shapes;
55
+
56
+ timer.start();
57
+ for (Tile* tile : tiles_) {
58
+ for (Shape *shape : tile->shapes()) {
59
+ if (shape->outer_polyline->is_on(Polyline::TRACKED_OUTER) || shape->outer_polyline->width() == 0) continue;
60
+ if (shape->outer_polyline->boundary())
61
+ { shape->outer_polyline->partition();
62
+ shape->outer_polyline->precalc();
63
+ }
64
+ }
65
+ }
66
+ tot_outer += timer.stop();
67
+
68
+ for (Tile* tile : tiles_) {
69
+ std::list<Shape*>& src = tile->shapes();
70
+ for (auto it = src.begin(); it != src.end(); )
71
+ { Shape* shape = *it;
72
+ if (shape->outer_polyline->is_on(Polyline::TRACKED_OUTER) || shape->outer_polyline->width() == 0)
73
+ { it++;
74
+ continue;
75
+ }
76
+
77
+ if (shape->outer_polyline->boundary() && !shape->outer_polyline->next_tile_eligible_shapes().empty()) {
78
+ Sequence* new_outer = nullptr;
79
+ std::list<std::vector<Point*>> new_inners = shape->inner_polylines;
80
+ Cursor cursor(*this, shape);
81
+ timer.start();
82
+ new_outer = cursor.join_outers();
83
+ tot_outer += timer.stop();
84
+
85
+ timer.start();
86
+ std::vector<Sequence*> new_inner_sequences = cursor.join_inners(new_outer);
87
+ tot_inner += timer.stop();
88
+
89
+ for (Sequence* s : new_inner_sequences) {
90
+ new_inners.push_back(s->to_vector());
91
+ delete s;
92
+ }
93
+ for (auto s : cursor.orphan_inners()) {
94
+ new_inners.push_back(s);
95
+ }
96
+ Polyline* polyline = new Polyline(tile, new_outer->to_vector());
97
+ Shape* shape = new Shape(polyline, new_inners);
98
+ shapes.push_back(shape);
99
+ polyline->shape = shape;
100
+ it++;
101
+ } else {
102
+ shapes.push_back(shape);
103
+ it = src.erase(it);
104
+ }
105
+ }
106
+ }
107
+ double past_tot_outer = tiles_.front()->benchmarks.outer + tiles_.back()->benchmarks.outer;
108
+ double past_tot_inner = tiles_.front()->benchmarks.inner + tiles_.back()->benchmarks.inner;
109
+ Benchmarks b{
110
+ tot_outer + past_tot_outer,
111
+ tot_inner + past_tot_inner
112
+ };
113
+ Tile* tile = new Tile(this->finder, tiles_.front()->start_x(), tiles_.back()->end_x(), tiles_.front()->name() + tiles_.back()->name(), b);
114
+ tile->assign_shapes(shapes);
115
+ return(tile);
116
+ }
117
+
@@ -0,0 +1,32 @@
1
+ /*
2
+ * Cluster.h
3
+ *
4
+ * Created on: 23 nov 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+
9
+ #pragma once
10
+ #include <vector>
11
+ #include <deque>
12
+ #include "Finder.h"
13
+ #include "Cluster.h"
14
+ #include "Hub.h"
15
+ #include "PartPool.h"
16
+
17
+ class Cluster {
18
+ private:
19
+ Finder *finder;
20
+ std::vector<Tile*> tiles_;
21
+ Hub *hub_ = nullptr;
22
+ public:
23
+ Cluster(Finder *finder, int height, int width);
24
+ virtual ~Cluster();
25
+ void add(Tile* tile);
26
+ Tile* merge_tiles();
27
+ const std::vector<Tile*> tiles() const { return tiles_; }
28
+ Hub* hub() { return hub_; }
29
+ static void list_to_string(std::vector<Point*> list);
30
+ PartPool parts_pool;
31
+ std::deque<Position> positions_pool;
32
+ };