contrek 1.2.8 → 1.3.0

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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +11 -0
  4. data/CHANGELOG.md +7 -1
  5. data/Gemfile +2 -0
  6. data/Gemfile.lock +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +2 -0
  9. data/contrek.gemspec +2 -0
  10. data/ext/cpp_polygon_finder/PolygonFinder/CMakeLists.txt +2 -4
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +118 -19
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +1 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +5 -7
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +4 -1
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +14 -15
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +2 -4
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +2 -2
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +13 -13
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +79 -354
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +6 -6
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +3 -2
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +8 -8
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +4 -4
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +3 -1
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.cpp +6 -6
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.h +3 -3
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Merger.cpp +4 -3
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +29 -9
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +3 -1
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +45 -30
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +18 -19
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +6 -5
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +2 -2
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +1 -1
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +4 -4
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +7 -7
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +2 -2
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +8 -2
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +4 -1
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp +19 -5
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.h +6 -2
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp +117 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.h +41 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +9 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +1 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp +4 -13
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.h +1 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +8 -8
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +2 -2
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +1 -1
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +2 -2
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +3 -3
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +1 -1
  54. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +3 -3
  55. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +10 -10
  56. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +66 -16
  57. data/ext/cpp_polygon_finder/extconf.rb +2 -0
  58. data/lib/contrek/bitmaps/bitmap.rb +2 -0
  59. data/lib/contrek/bitmaps/chunky_bitmap.rb +13 -0
  60. data/lib/contrek/bitmaps/painting.rb +2 -0
  61. data/lib/contrek/bitmaps/png_bitmap.rb +2 -0
  62. data/lib/contrek/bitmaps/raw_bitmap.rb +2 -0
  63. data/lib/contrek/bitmaps/rgb_color.rb +2 -0
  64. data/lib/contrek/bitmaps/rgb_cpp_color.rb +2 -0
  65. data/lib/contrek/bitmaps/sample_generator.rb +2 -0
  66. data/lib/contrek/cpp/cpp_concurrent_finder.rb +2 -0
  67. data/lib/contrek/cpp/cpp_concurrent_horizontal_merger.rb +2 -0
  68. data/lib/contrek/cpp/cpp_concurrent_merger.rb +2 -0
  69. data/lib/contrek/cpp/cpp_concurrent_streaming_merger.rb +11 -0
  70. data/lib/contrek/cpp/cpp_concurrent_vertical_merger.rb +2 -0
  71. data/lib/contrek/cpp/cpp_result.rb +2 -0
  72. data/lib/contrek/cpp/cpp_tempfile.rb +28 -0
  73. data/lib/contrek/finder/bounds.rb +2 -0
  74. data/lib/contrek/finder/concurrent/clipped_polygon_finder.rb +2 -0
  75. data/lib/contrek/finder/concurrent/cluster.rb +3 -1
  76. data/lib/contrek/finder/concurrent/cursor.rb +2 -0
  77. data/lib/contrek/finder/concurrent/end_point.rb +2 -0
  78. data/lib/contrek/finder/concurrent/fake_cluster.rb +2 -0
  79. data/lib/contrek/finder/concurrent/finder.rb +6 -0
  80. data/lib/contrek/finder/concurrent/horizontal_merger.rb +2 -0
  81. data/lib/contrek/finder/concurrent/hub.rb +2 -0
  82. data/lib/contrek/finder/concurrent/inner_polyline.rb +2 -0
  83. data/lib/contrek/finder/concurrent/listable.rb +2 -0
  84. data/lib/contrek/finder/concurrent/merger.rb +4 -0
  85. data/lib/contrek/finder/concurrent/part.rb +13 -0
  86. data/lib/contrek/finder/concurrent/partitionable.rb +33 -17
  87. data/lib/contrek/finder/concurrent/polyline.rb +2 -0
  88. data/lib/contrek/finder/concurrent/poolable.rb +2 -0
  89. data/lib/contrek/finder/concurrent/position.rb +2 -0
  90. data/lib/contrek/finder/concurrent/queueable.rb +2 -0
  91. data/lib/contrek/finder/concurrent/sequence.rb +2 -0
  92. data/lib/contrek/finder/concurrent/shape.rb +2 -0
  93. data/lib/contrek/finder/concurrent/streaming_merger.rb +89 -0
  94. data/lib/contrek/finder/concurrent/tile.rb +2 -0
  95. data/lib/contrek/finder/concurrent/vertical_merger.rb +8 -2
  96. data/lib/contrek/finder/list.rb +2 -0
  97. data/lib/contrek/finder/list_entry.rb +2 -0
  98. data/lib/contrek/finder/listable.rb +2 -0
  99. data/lib/contrek/finder/lists.rb +2 -0
  100. data/lib/contrek/finder/node.rb +2 -0
  101. data/lib/contrek/finder/node_cluster.rb +3 -1
  102. data/lib/contrek/finder/polygon_finder.rb +4 -1
  103. data/lib/contrek/finder/result.rb +2 -0
  104. data/lib/contrek/map/mercator_projection.rb +2 -0
  105. data/lib/contrek/matchers/matcher.rb +2 -0
  106. data/lib/contrek/matchers/matcher_hsb.rb +2 -0
  107. data/lib/contrek/matchers/value_not_matcher.rb +2 -0
  108. data/lib/contrek/reducers/linear_reducer.rb +2 -0
  109. data/lib/contrek/reducers/reducer.rb +2 -0
  110. data/lib/contrek/reducers/uniq_reducer.rb +2 -0
  111. data/lib/contrek/reducers/visvalingam_reducer.rb +2 -0
  112. data/lib/contrek/shared/result.rb +2 -0
  113. data/lib/contrek/version.rb +3 -1
  114. data/lib/contrek.rb +5 -0
  115. metadata +11 -5
@@ -61,12 +61,12 @@ struct pf_Options {
61
61
  struct ProcessResult {
62
62
  int groups;
63
63
  int width, height;
64
+ int versus;
64
65
  bool has_bounds = false;
65
66
  std::map<std::string, double> benchmarks;
66
67
  std::list<Polygon> polygons;
67
68
  std::string named_sequence;
68
69
  std::vector<std::pair<int, int>> treemap;
69
- std::vector<Point> cloned_points_storage;
70
70
 
71
71
  void draw_on_bitmap(RawBitmap& canvas) const;
72
72
 
@@ -74,12 +74,12 @@ struct ProcessResult {
74
74
  int counter = 0;
75
75
  for (const auto& polygon : polygons) {
76
76
  std::cout << counter << " - " << "outer" << "\n";
77
- for (const Point* p : polygon.outer) std::cout << p->toString();
77
+ for (const Point& p : polygon.outer) std::cout << p.toString();
78
78
  bool first = true;
79
79
  for (const auto& seq : polygon.inner) {
80
80
  if (!first) std::cout << "\n";
81
81
  first = false;
82
- for (const Point* p : seq) std::cout << p->toString();
82
+ for (const Point& p : seq) std::cout << p.toString();
83
83
  }
84
84
  std::cout << "\n" << polygon.bounds.to_string() <<"\n";
85
85
  counter++;
@@ -95,61 +95,15 @@ struct ProcessResult {
95
95
 
96
96
  void translate(int x) {
97
97
  for (auto& polygon : polygons) {
98
- for (Point* p : polygon.outer) p->x += x;
99
- for (const auto& seq : polygon.inner) {
100
- for (Point* p : seq) p->x += x;
98
+ for (Point& p : polygon.outer) p.x += x;
99
+ for (auto& seq : polygon.inner) {
100
+ for (Point& p : seq) p.x += x;
101
101
  }
102
102
  polygon.bounds.min_x += x;
103
103
  polygon.bounds.max_x += x;
104
104
  }
105
105
  }
106
106
 
107
- ProcessResult* clone() const {
108
- ProcessResult* new_res = new ProcessResult();
109
- new_res->groups = this->groups;
110
- new_res->width = this->width;
111
- new_res->height = this->height;
112
- new_res->benchmarks = this->benchmarks;
113
- new_res->named_sequence = this->named_sequence;
114
- new_res->treemap = this->treemap;
115
-
116
- size_t estimated_points = 0;
117
- for (const auto& poly : this->polygons) {
118
- estimated_points += poly.outer.size();
119
- for (const auto& seq : poly.inner) estimated_points += seq.size();
120
- }
121
- new_res->cloned_points_storage.reserve(estimated_points);
122
-
123
- for (const auto& poly : this->polygons) {
124
- Polygon new_poly;
125
- new_poly.bounds = poly.bounds;
126
- new_poly.outer.reserve(poly.outer.size());
127
- // outer
128
- for (const Point* p : poly.outer) {
129
- if (p) {
130
- new_res->cloned_points_storage.push_back(Point(p->x, p->y));
131
- size_t idx = new_res->cloned_points_storage.size() - 1;
132
- new_poly.outer.push_back(&new_res->cloned_points_storage[idx]);
133
- }
134
- }
135
- // inner
136
- for (const auto& seq : poly.inner) {
137
- std::vector<Point*> new_seq;
138
- new_seq.reserve(seq.size());
139
- for (const Point* p : seq) {
140
- if (p) {
141
- new_res->cloned_points_storage.push_back(Point(p->x, p->y));
142
- size_t idx = new_res->cloned_points_storage.size() - 1;
143
- new_seq.push_back(&new_res->cloned_points_storage[idx]);
144
- }
145
- }
146
- new_poly.inner.push_back(new_seq);
147
- }
148
- new_res->polygons.push_back(new_poly);
149
- }
150
- return new_res;
151
- }
152
-
153
107
  void to_svg_stream(std::ostream& os) const {
154
108
  os << "<svg xmlns=\"http://www.w3.org/2000/svg\" "
155
109
  << "width=\"" << width << "\" height=\"" << height << "\">\n";
@@ -158,11 +112,10 @@ struct ProcessResult {
158
112
  if (!poly.outer.empty()) {
159
113
  os << "<polygon points=\"";
160
114
  bool first = true;
161
- for (const Point* p : poly.outer) {
162
- if (!p) continue;
115
+ for (const Point& p : poly.outer) {
163
116
  if (!first) os << " ";
164
117
  first = false;
165
- os << p->x << "," << p->y;
118
+ os << p.x << "," << p.y;
166
119
  }
167
120
  os << "\" fill=\"none\" stroke=\"red\" stroke-width=\"1\"/>\n";
168
121
  }
@@ -171,11 +124,10 @@ struct ProcessResult {
171
124
  if (sequence.empty()) continue;
172
125
  os << "<polygon points=\"";
173
126
  bool first = true;
174
- for (const Point* p : sequence) {
175
- if (!p) continue;
127
+ for (const Point& p : sequence) {
176
128
  if (!first) os << " ";
177
129
  first = false;
178
- os << p->x << "," << p->y;
130
+ os << p.x << "," << p.y;
179
131
  }
180
132
  os << "\" fill=\"none\" stroke=\"green\" stroke-width=\"1\"/>\n";
181
133
  }
@@ -207,330 +159,103 @@ class PolygonFinder {
207
159
  std::map<std::string, double> reports;
208
160
  void scan();
209
161
  CpuTimer cpu_timer;
210
- /*
162
+
211
163
  template <typename M, typename F>
212
164
  void run_loop(M* specific_matcher, F&& fetch_color, int offset) {
213
165
  int img_h = this->source_bitmap->h();
214
166
  int bpp = this->source_bitmap->get_bytes_per_pixel();
167
+
215
168
  for (int y = 0; y < img_h; y++) {
216
169
  const unsigned char* row_ptr = this->source_bitmap->get_row_ptr(y);
217
170
  const unsigned char* p = row_ptr + (this->start_x * bpp);
171
+
218
172
  int min_x = 0;
219
173
  bool matching = false;
220
174
  unsigned char last_red_value = 0;
221
- for (int x = this->start_x; x < this->end_x; x++) {
222
- unsigned int color = fetch_color(p);
223
- unsigned char current_val = p[0];
224
- p += bpp;
225
- if (specific_matcher->match(color)) {
226
- if (!matching) {
227
- min_x = x;
228
- last_red_value = current_val;
229
- matching = true;
230
- }
231
- if (x == this->end_x - 1) {
232
- this->node_cluster->add_node(min_x, x, y, last_red_value, offset);
233
- matching = false;
234
- }
235
- } else if (matching) {
236
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
237
- matching = false;
238
- }
239
- }
240
- }
241
- }*/
242
-
243
- template <typename M, typename F>
244
- void run_loop(M* specific_matcher, F&& fetch_color, int offset) {
245
- int img_h = this->source_bitmap->h();
246
- int bpp = this->source_bitmap->get_bytes_per_pixel();
247
-
248
- for (int y = 0; y < img_h; y++) {
249
- const unsigned char* row_ptr = this->source_bitmap->get_row_ptr(y);
250
- const unsigned char* p = row_ptr + (this->start_x * bpp);
251
-
252
- int min_x = 0;
253
- bool matching = false;
254
- unsigned char last_red_value = 0;
255
-
256
- int x = this->start_x;
257
-
258
- if (bpp == 4) {
259
- for (; x <= this->end_x - 4; x += 4) {
260
- // 1. Unico accesso alla RAM per pixel: leggiamo i 4 byte completi
261
- unsigned int c0 = fetch_color(p);
262
- unsigned int c1 = fetch_color(p + 4);
263
- unsigned int c2 = fetch_color(p + 8);
264
- unsigned int c3 = fetch_color(p + 12);
265
-
266
- // 2. Estrazione a costo zero dai registri della CPU (Operazione bitwise, NO RAM)
267
- // Se fetch_color ritorna il mascheramento standard, il primo byte si prende con il cast o lo shift
268
- unsigned char v0 = static_cast<unsigned char>(c0);
269
- unsigned char v1 = static_cast<unsigned char>(c1);
270
- unsigned char v2 = static_cast<unsigned char>(c2);
271
- unsigned char v3 = static_cast<unsigned char>(c3);
272
175
 
273
- p += 16;
176
+ int x = this->start_x;
274
177
 
275
- bool m0 = specific_matcher->match(c0);
276
- bool m1 = specific_matcher->match(c1);
277
- bool m2 = specific_matcher->match(c2);
278
- bool m3 = specific_matcher->match(c3);
178
+ if (bpp == 4) {
179
+ for (; x <= this->end_x - 4; x += 4) {
180
+ // read 4 pixels (16 bytes)
181
+ unsigned int c0 = fetch_color(p);
182
+ unsigned int c1 = fetch_color(p + 4);
183
+ unsigned int c2 = fetch_color(p + 8);
184
+ unsigned int c3 = fetch_color(p + 12);
279
185
 
280
- // [Resto della logica dei pixel 0, 1, 2, 3 invariata...]
281
- if (m0) {
282
- if (!matching) { min_x = x; last_red_value = v0; matching = true; }
283
- } else if (matching) {
284
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
285
- matching = false;
286
- }
186
+ // extracts value (used as debugging segment label)
187
+ unsigned char v0 = static_cast<unsigned char>(c0);
188
+ unsigned char v1 = static_cast<unsigned char>(c1);
189
+ unsigned char v2 = static_cast<unsigned char>(c2);
190
+ unsigned char v3 = static_cast<unsigned char>(c3);
287
191
 
288
- if (m1) {
289
- if (!matching) { min_x = x + 1; last_red_value = v1; matching = true; }
290
- } else if (matching) {
291
- this->node_cluster->add_node(min_x, x, y, last_red_value, offset);
292
- matching = false;
293
- }
192
+ p += 16;
294
193
 
295
- if (m2) {
296
- if (!matching) { min_x = x + 2; last_red_value = v2; matching = true; }
297
- } else if (matching) {
298
- this->node_cluster->add_node(min_x, x + 1, y, last_red_value, offset);
299
- matching = false;
300
- }
194
+ bool m0 = specific_matcher->match(c0);
195
+ bool m1 = specific_matcher->match(c1);
196
+ bool m2 = specific_matcher->match(c2);
197
+ bool m3 = specific_matcher->match(c3);
301
198
 
302
- if (m3) {
303
- if (!matching) { min_x = x + 3; last_red_value = v3; matching = true; }
304
- } else if (matching) {
305
- this->node_cluster->add_node(min_x, x + 2, y, last_red_value, offset);
306
- matching = false;
307
- }
199
+ if (m0) {
200
+ if (!matching) {
201
+ min_x = x; last_red_value = v0; matching = true;
308
202
  }
309
- }
310
-
311
- // --- CLEANUP SCALARE ---
312
- for (; x < this->end_x; x++) {
313
- unsigned int color = fetch_color(p);
314
- // Applichiamo la stessa ottimizzazione anche qui
315
- unsigned char current_val = static_cast<unsigned char>(color);
316
- p += bpp;
317
-
318
- if (specific_matcher->match(color)) {
319
- if (!matching) {
320
- min_x = x;
321
- last_red_value = current_val;
322
- matching = true;
323
- }
324
- } else if (matching) {
325
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
326
- matching = false;
327
- }
328
- }
329
-
330
- if (matching) {
331
- this->node_cluster->add_node(min_x, this->end_x - 1, y, last_red_value, offset);
332
- }
333
- }
334
- }
335
-
336
- /*template <typename M, typename F>
337
- void run_loop(M* specific_matcher, F&& fetch_color, int offset) {
338
- int img_h = this->source_bitmap->h();
339
- int bpp = this->source_bitmap->get_bytes_per_pixel();
340
-
341
- for (int y = 0; y < img_h; y++) {
342
- const unsigned char* row_ptr = this->source_bitmap->get_row_ptr(y);
343
- const unsigned char* p = row_ptr + (this->start_x * bpp);
344
-
345
- int min_x = 0;
346
- bool matching = false;
347
- unsigned char last_red_value = 0;
348
-
349
- int x = this->start_x;
350
-
351
- // --- IL TUO SWEET SPOT: UNROLLING A 4 VIE RIFINITO ---
352
- if (bpp == 4) {
353
- for (; x <= this->end_x - 4; x += 4) {
354
- // Leggiamo in sequenza stretta per ottimizzare i register e la cache L1
355
- unsigned int c0 = fetch_color(p);
356
- unsigned char v0 = p[0];
357
-
358
- unsigned int c1 = fetch_color(p + 4);
359
- unsigned char v1 = p[4];
360
-
361
- unsigned int c2 = fetch_color(p + 8);
362
- unsigned char v2 = p[8];
363
-
364
- unsigned int c3 = fetch_color(p + 12);
365
- unsigned char v3 = p[12];
366
-
367
- p += 16; // Spostato qui: avanza di 4 pixel RGBA precisi
368
-
369
- bool m0 = specific_matcher->match(c0);
370
- bool m1 = specific_matcher->match(c1);
371
- bool m2 = specific_matcher->match(c2);
372
- bool m3 = specific_matcher->match(c3);
373
-
374
- // Pixel 0
375
- if (m0) {
376
- if (!matching) { min_x = x; last_red_value = v0; matching = true; }
377
- } else if (matching) {
378
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
379
- matching = false;
380
- }
381
-
382
- // Pixel 1
383
- if (m1) {
384
- if (!matching) { min_x = x + 1; last_red_value = v1; matching = true; }
385
- } else if (matching) {
386
- this->node_cluster->add_node(min_x, x, y, last_red_value, offset);
387
- matching = false;
388
- }
389
-
390
- // Pixel 2
391
- if (m2) {
392
- if (!matching) { min_x = x + 2; last_red_value = v2; matching = true; }
393
- } else if (matching) {
394
- this->node_cluster->add_node(min_x, x + 1, y, last_red_value, offset);
395
- matching = false;
396
- }
203
+ } else if (matching) {
204
+ this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
205
+ matching = false;
206
+ }
397
207
 
398
- // Pixel 3
399
- if (m3) {
400
- if (!matching) { min_x = x + 3; last_red_value = v3; matching = true; }
401
- } else if (matching) {
402
- this->node_cluster->add_node(min_x, x + 2, y, last_red_value, offset);
403
- matching = false;
404
- }
208
+ if (m1) {
209
+ if (!matching) {
210
+ min_x = x + 1; last_red_value = v1; matching = true;
405
211
  }
406
- }
212
+ } else if (matching) {
213
+ this->node_cluster->add_node(min_x, x, y, last_red_value, offset);
214
+ matching = false;
215
+ }
407
216
 
408
- // --- CLEANUP SCALARE PER I RIMANENTI ---
409
- for (; x < this->end_x; x++) {
410
- unsigned int color = fetch_color(p);
411
- unsigned char current_val = p[0];
412
- p += bpp;
413
-
414
- if (specific_matcher->match(color)) {
415
- if (!matching) {
416
- min_x = x;
417
- last_red_value = current_val;
418
- matching = true;
419
- }
420
- } else if (matching) {
421
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
422
- matching = false;
217
+ if (m2) {
218
+ if (!matching) {
219
+ min_x = x + 2; last_red_value = v2; matching = true;
423
220
  }
424
- }
425
-
426
- // --- CHIUSURA DI SICUREZZA FINE RIGA ---
427
- if (matching) {
428
- this->node_cluster->add_node(min_x, this->end_x - 1, y, last_red_value, offset);
429
- }
430
- }
431
- }*/
432
-
433
-
434
-
435
- /*
436
-
437
- #include <cstdint>
438
-
439
- template <typename M, typename F>
440
- void run_loop(M* specific_matcher, F&& fetch_color, int offset) {
441
- int img_h = this->source_bitmap->h();
442
- int bpp = this->source_bitmap->get_bytes_per_pixel();
443
-
444
- for (int y = 0; y < img_h; y++) {
445
- const unsigned char* row_ptr = this->source_bitmap->get_row_ptr(y);
446
- const unsigned char* p = row_ptr + (this->start_x * bpp);
447
-
448
- int min_x = 0;
449
- bool matching = false;
450
- unsigned char last_red_value = 0;
451
-
452
- int x = this->start_x;
453
-
454
- // --- LINEA 1: UNROLLING A 4 VIE (SIMD FRIENDLY, NO DEPENDENCY) ---
455
- if (bpp == 4) {
456
- for (; x <= this->end_x - 4; x += 4) {
457
- // Carichiamo 4 pixel in variabili separate (zero dipendenze tra loro)
458
- unsigned int c0 = fetch_color(p);
459
- unsigned int c1 = fetch_color(p + 4);
460
- unsigned int c2 = fetch_color(p + 8);
461
- unsigned int c3 = fetch_color(p + 12);
462
-
463
- unsigned char v0 = p[0];
464
- unsigned char v1 = p[4];
465
- unsigned char v2 = p[8];
466
- unsigned char v3 = p[12];
467
-
468
- p += 16; // Avanza di 4 pixel (4 * 4 byte)
469
-
470
- // Eseguiamo il match in parallelo. Il compilatore trasforma questo in istruzioni vettoriali
471
- bool m0 = specific_matcher->match(c0);
472
- bool m1 = specific_matcher->match(c1);
473
- bool m2 = specific_matcher->match(c2);
474
- bool m3 = specific_matcher->match(c3);
475
-
476
- // Pixel 0
477
- if (m0) {
478
- if (!matching) { min_x = x; last_red_value = v0; matching = true; }
479
- } else if (matching) {
480
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
481
- matching = false;
482
- }
483
-
484
- // Pixel 1
485
- if (m1) {
486
- if (!matching) { min_x = x + 1; last_red_value = v1; matching = true; }
487
- } else if (matching) {
488
- this->node_cluster->add_node(min_x, x, y, last_red_value, offset);
489
- matching = false;
490
- }
491
-
492
- // Pixel 2
493
- if (m2) {
494
- if (!matching) { min_x = x + 2; last_red_value = v2; matching = true; }
495
- } else if (matching) {
496
- this->node_cluster->add_node(min_x, x + 1, y, last_red_value, offset);
497
- matching = false;
498
- }
221
+ } else if (matching) {
222
+ this->node_cluster->add_node(min_x, x + 1, y, last_red_value, offset);
223
+ matching = false;
224
+ }
499
225
 
500
- // Pixel 3
501
- if (m3) {
502
- if (!matching) { min_x = x + 3; last_red_value = v3; matching = true; }
503
- } else if (matching) {
504
- this->node_cluster->add_node(min_x, x + 2, y, last_red_value, offset);
505
- matching = false;
506
- }
226
+ if (m3) {
227
+ if (!matching) {
228
+ min_x = x + 3; last_red_value = v3; matching = true;
507
229
  }
230
+ } else if (matching) {
231
+ this->node_cluster->add_node(min_x, x + 2, y, last_red_value, offset);
232
+ matching = false;
233
+ }
508
234
  }
235
+ }
509
236
 
510
- // --- LINEA 2: SCALAR CLEANUP ---
511
- for (; x < this->end_x; x++) {
512
- unsigned int color = fetch_color(p);
513
- unsigned char current_val = p[0];
514
- p += bpp;
515
-
516
- if (specific_matcher->match(color)) {
517
- if (!matching) {
518
- min_x = x;
519
- last_red_value = current_val;
520
- matching = true;
521
- }
522
- } else if (matching) {
523
- this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
524
- matching = false;
525
- }
237
+ // remaining pixels (width not a multiple of 4)
238
+ for (; x < this->end_x; x++) {
239
+ unsigned int color = fetch_color(p);
240
+ unsigned char current_val = static_cast<unsigned char>(color);
241
+ p += bpp;
242
+ if (specific_matcher->match(color)) {
243
+ if (!matching) {
244
+ min_x = x;
245
+ last_red_value = current_val;
246
+ matching = true;
247
+ }
248
+ } else if (matching) {
249
+ this->node_cluster->add_node(min_x, x - 1, y, last_red_value, offset);
250
+ matching = false;
526
251
  }
252
+ }
527
253
 
528
- // --- CHIUSURA DI SICUREZZA ---
529
- if (matching) {
530
- this->node_cluster->add_node(min_x, this->end_x - 1, y, last_red_value, offset);
531
- }
254
+ if (matching) {
255
+ this->node_cluster->add_node(min_x, this->end_x - 1, y, last_red_value, offset);
256
+ }
532
257
  }
533
- }*/
258
+ }
534
259
 
535
260
  public:
536
261
  PolygonFinder(Bitmap *bitmap,
@@ -18,7 +18,7 @@
18
18
  #include "../../CpuTimer.h"
19
19
 
20
20
  Cluster::Cluster(Finder *finder, int height, int start_x, int end_x)
21
- : finder(finder)
21
+ : finder_(finder)
22
22
  { tiles_.reserve(2); // only two (left|right)
23
23
  this->hub_ = new Hub(height);
24
24
  }
@@ -40,16 +40,16 @@ void Cluster::add(Tile* tile) {
40
40
  }
41
41
  }
42
42
 
43
- void Cluster::list_to_string(std::vector<Point*> list)
43
+ void Cluster::list_to_string(std::vector<Point> list)
44
44
  { std::cout << "(" << &list << ") ";
45
- for (Point* point : list) {
46
- std::cout << point->toString();
45
+ for (const Point& point : list) {
46
+ std::cout << point.toString();
47
47
  }
48
48
  std::cout << std::endl;
49
49
  }
50
50
 
51
51
  Tile* Cluster::merge_tiles() {
52
- bool treemap = this->finder->options().treemap;
52
+ bool treemap = this->finder_->options().treemap;
53
53
  double tot_inner = 0;
54
54
  double tot_outer = 0;
55
55
  CpuTimer timer;
@@ -141,7 +141,7 @@ Tile* Cluster::merge_tiles() {
141
141
  };
142
142
 
143
143
  Tile* tile = new Tile(
144
- this->finder, tiles_.front()->start_x(), tiles_.back()->end_x(), tiles_.front()->name() + tiles_.back()->name(), b);
144
+ this->finder_, tiles_.front()->start_x(), tiles_.back()->end_x(), tiles_.front()->name() + tiles_.back()->name(), b);
145
145
 
146
146
  tile->assign_shapes(new_shapes);
147
147
  for (Tile* old_tile : tiles_) {
@@ -18,7 +18,7 @@
18
18
 
19
19
  class Cluster {
20
20
  private:
21
- Finder *finder;
21
+ Finder *finder_;
22
22
  std::vector<Tile*> tiles_;
23
23
  Hub *hub_ = nullptr;
24
24
  void assign_ancestry(Shape *shape, InnerPolyline* inner_polyline);
@@ -31,7 +31,8 @@ class Cluster {
31
31
  Tile* merge_tiles();
32
32
  const std::vector<Tile*> tiles() const { return tiles_; }
33
33
  Hub* hub() { return hub_; }
34
- static void list_to_string(std::vector<Point*> list);
34
+ static void list_to_string(std::vector<Point> list);
35
35
  PartPool parts_pool;
36
36
  std::deque<Position> positions_pool;
37
+ const Finder* finder() const { return finder_; };
37
38
  };
@@ -29,7 +29,7 @@ Sequence* Cursor::join_outers()
29
29
  this->shapes_sequence_,
30
30
  outer_joined_polyline);
31
31
 
32
- if (*outer_joined_polyline->head->payload == *outer_joined_polyline->tail->payload &&
32
+ if (outer_joined_polyline->head->payload == outer_joined_polyline->tail->payload &&
33
33
  this->cluster.tiles().front()->left() &&
34
34
  this->cluster.tiles().back()->right()) outer_joined_polyline->pop();
35
35
 
@@ -151,11 +151,11 @@ std::vector<InnerPolyline*> Cursor::join_inners(Sequence* outer_seq, bool treema
151
151
  retme_sequence->move_from(*part, [&](QNode<Point>* pos) -> bool {
152
152
  Position *position = static_cast<Position*>(pos);
153
153
  if (part->is(Part::ADDED) &&
154
- !(position->payload->y >= bounds.min &&
155
- position->payload->y <= bounds.max)) {
154
+ !(position->payload.y >= bounds.min &&
155
+ position->payload.y <= bounds.max)) {
156
156
  return(false);
157
157
  }
158
- return(!(polyline->tile->tg_border(*position->payload) && position->end_point()->tracked_outer));
158
+ return(!(polyline->tile->tg_border(position->payload) && position->end_point()->tracked_outer));
159
159
  });
160
160
  }
161
161
  if (retme_sequence->is_not_vertical()) {
@@ -175,7 +175,7 @@ void Cursor::mark_children(std::vector<EndPoint*>& end_points, const Polyline* o
175
175
  for (size_t i = 0; i + 1 < end_points.size(); i += 2) {
176
176
  const auto& a = end_points[i];
177
177
  const auto& b = end_points[i + 1];
178
- auto [y_min, y_max] = std::minmax(a->get_point()->y, b->get_point()->y);
178
+ auto [y_min, y_max] = std::minmax(a->get_point().y, b->get_point().y);
179
179
  for (int y = y_min + 1; y < y_max; ++y) {
180
180
  EndPoint* end_point = this->cluster.hub()->get(y);
181
181
  if (end_point) {
@@ -199,9 +199,9 @@ void Cursor::traverse_inner(Part* act_part, std::vector<Part*>& all_parts, Bound
199
199
  auto [min_it, max_it] = std::minmax_element(
200
200
  points.begin(),
201
201
  points.end(),
202
- [](Point* a, Point* b) { return a->y < b->y; });
203
- bounds.min = std::min(bounds.min, (*min_it)->y);
204
- bounds.max = std::max(bounds.max, (*max_it)->y);
202
+ [](const Point& a, const Point& b) { return a.y < b.y; });
203
+ bounds.min = std::min(bounds.min, min_it->y);
204
+ bounds.max = std::max(bounds.max, max_it->y);
205
205
  }
206
206
  if (act_part->innerable()) {
207
207
  all_parts.push_back(act_part);
@@ -16,15 +16,15 @@ class Part;
16
16
 
17
17
  class EndPoint {
18
18
  public:
19
- EndPoint() : point_(nullptr) {}
19
+ EndPoint() {}
20
20
 
21
- void set_point(Point* p) { point_ = p; }
22
- Point* get_point() const { return point_; }
21
+ void set_point(const Point& p) { point_ = p; }
22
+ const Point& get_point() const { return point_; }
23
23
  std::vector<Queueable<Point>*>& queues() { return queues_; }
24
24
  bool queues_include(Queueable<Point>* q) const;
25
25
  bool tracked_outer = false;
26
26
 
27
27
  private:
28
- Point* point_;
28
+ Point point_;
29
29
  std::vector<Queueable<Point>*> queues_;
30
30
  };
@@ -35,7 +35,6 @@ class Finder : public Poolable {
35
35
  Matcher *matcher;
36
36
  pf_Options options_;
37
37
  std::vector<std::string> input_options;
38
- Tile* whole_tile = nullptr;
39
38
  std::queue<ClippedPolygonFinder*> finders;
40
39
  std::mutex finders_mutex;
41
40
  std::map<std::string, double> reports;
@@ -45,6 +44,7 @@ class Finder : public Poolable {
45
44
  Queue<Tile*> tiles_;
46
45
  int maximum_width_;
47
46
  int height = 0;
47
+ Tile* whole_tile = nullptr;
48
48
  void process_tiles();
49
49
 
50
50
  public:
@@ -56,4 +56,6 @@ class Finder : public Poolable {
56
56
  virtual ProcessResult* process_info();
57
57
  const pf_Options& options() const { return options_; }
58
58
  Queue<Tile*>& tiles() { return tiles_; }
59
+ virtual bool transpose() const { return false; }
60
+ int versus;
59
61
  };