contrek 1.2.4 → 1.2.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0df584b1fe92f70cb27f479a6d7705545f662b8758a4843bf966fe92d90c4c9d
4
- data.tar.gz: 2dfe6f8b0cc96298858f5055158ba439644d24a9921166c572e91cd5df17780b
3
+ metadata.gz: 32d1d662c0c6c0c1dc6ffcde36090b188e7d3abd39fc5dd7ba0887aa62526b27
4
+ data.tar.gz: df8b75836abf466043587f22995f12e13c3ed908b60a4fcda97216e803458540
5
5
  SHA512:
6
- metadata.gz: d97742b1bc4f3688a8d083d25873da8db709b69c42c8068d02cfe6fe3569acac159f3d1a37c31128a7809b0e9851ba5e9da15c801f18c514189e53f4bc39440a
7
- data.tar.gz: ee34393dc9713f62de0560b5d6538e7e9ffd6ff38358429f14f7ab7efb3cde201f2461d4ec209ed906a0a0e1e6aa0eb013040dddf290856400f632131e4c3622
6
+ metadata.gz: 33c9e4906109bcd7cee694401b3946b0fe2e5800c551bc20a4ea428bdb7cbe7eb456a2e7cadd57327ca93bf65491284e4566b2caaa9e0ea28a5c771c8e50510b
7
+ data.tar.gz: ede6984f06ebef2b9672e1f1c0569428b25332e9bb14249a8341fdc1e4f11c493a066015a496bd9d19baec57a97bf98d4d99d23262a4a7dac93757c129e8c441
data/CHANGELOG.md CHANGED
@@ -95,7 +95,14 @@ All notable changes to this project will be documented in this file.
95
95
 
96
96
  ## [1.2.3] - 2026-05-23
97
97
  ### Changed
98
- ### Changed
99
98
  * **SVG Conversion:** Added utility methods to convert point coordinates directly into SVG paths.
100
99
  * **Contrek API & RAII Architecture:** Refactored the Contrek API to utilize an RAII (Resource Acquisition Is Initialization) pattern, safely wrapping both the trace engine and the processing results within a unified context lifecycle shell.
101
100
  * **ProcessResult Memory Management:** Updated `ProcessResult` to properly manage resource deallocation during cloning operations, ensuring deep-copied or moved internal points are automatically and safely freed when the context scope ends.
101
+
102
+ ## [1.2.4] - 2026-05-26
103
+ ### Changed
104
+ * Fixed an issue in connectivity8 tracing mode that, under specific rare conditions, disrupted the topological continuity of external contours in favor of internal ones.
105
+
106
+ ## [1.2.5] - 2026-05-27
107
+ ### Changed
108
+ - **Refactored `ProcessResult.clone()`:** Switched from fragmented dynamic allocation to a contiguous `std::vector` with explicit `.reserve()`. Eliminates heap fragmentation during high-res streaming.
@@ -17,6 +17,8 @@
17
17
  #include <cstring>
18
18
  #include <algorithm>
19
19
  #include <cstdio>
20
+ #include <sys/resource.h>
21
+
20
22
  #include "polygon/finder/PolygonFinder.h"
21
23
  #include "polygon/finder/concurrent/ClippedPolygonFinder.h"
22
24
  #include "polygon/bitmaps/Bitmap.h"
@@ -260,6 +262,16 @@ void Tests::test_h()
260
262
  delete right_result;
261
263
  }
262
264
 
265
+ double get_peak_rss() {
266
+ struct rusage r_usage;
267
+ getrusage(RUSAGE_SELF, &r_usage);
268
+ #ifdef __APPLE__
269
+ return r_usage.ru_maxrss / (1024.0 * 1024.0);
270
+ #else
271
+ return r_usage.ru_maxrss / 1024.0;
272
+ #endif
273
+ }
274
+
263
275
  /* In this example, PNG data is read by streaming into a user-defined buffer height.
264
276
  Contrek scans each stripe and extracts the polygons. Finally, it merges all
265
277
  polygons from every stripe as if they had been read from a single image and saves
@@ -303,7 +315,7 @@ void stream_png_image(const std::string& filepath, uint32_t stripe_height) {
303
315
  }
304
316
 
305
317
  size_t row_size = static_cast<size_t>(total_width) * 4;
306
- // main strpes loop
318
+ // main stripes loop
307
319
  for (uint32_t current_y_offset = 0; current_y_offset < total_height; current_y_offset += stripe_height) {
308
320
  int uncovered_height = total_height - current_y_offset;
309
321
 
@@ -366,4 +378,5 @@ void stream_png_image(const std::string& filepath, uint32_t stripe_height) {
366
378
 
367
379
  void Tests::test_i() {
368
380
  stream_png_image("../images/graphs_1024x1024.png", 300);
381
+ std::cout << "Memory usage peak: " << get_peak_rss() << " MB" << std::endl;
369
382
  }
@@ -62,6 +62,7 @@ struct Point {
62
62
  return x == other.x && y == other.y;
63
63
  }
64
64
  Point(int x_, int y_) : x(x_), y(y_) {}
65
+ Point() : x(0), y(0) {}
65
66
  };
66
67
 
67
68
  class Node : public Listable {
@@ -103,7 +103,6 @@ void PolygonFinder::scan() {
103
103
  ProcessResult* PolygonFinder::process_info() {
104
104
  ProcessResult *pr = new ProcessResult();
105
105
  pr->groups = this->node_cluster->sequences.size();
106
- pr->polygons = std::move(this->node_cluster->polygons);
107
106
  pr->benchmarks = std::move(this->reports);
108
107
  pr->treemap = this->node_cluster->treemap;
109
108
  pr->width = this->source_bitmap->w();
@@ -124,6 +123,7 @@ ProcessResult* PolygonFinder::process_info() {
124
123
  pr->named_sequence = sequence;
125
124
  }
126
125
  else pr->named_sequence = "";
126
+ pr->polygons = std::move(this->node_cluster->polygons);
127
127
  return(pr);
128
128
  }
129
129
 
@@ -63,7 +63,7 @@ struct ProcessResult {
63
63
  std::list<Polygon> polygons;
64
64
  std::string named_sequence;
65
65
  std::vector<std::pair<int, int>> treemap;
66
- std::vector<std::unique_ptr<Point>> cloned_points_storage;
66
+ std::vector<Point> cloned_points_storage;
67
67
 
68
68
  void draw_on_bitmap(RawBitmap& canvas) const;
69
69
 
@@ -119,22 +119,25 @@ struct ProcessResult {
119
119
 
120
120
  for (const auto& poly : this->polygons) {
121
121
  Polygon new_poly;
122
- // bounds
123
122
  new_poly.bounds = poly.bounds;
123
+ new_poly.outer.reserve(poly.outer.size());
124
124
  // outer
125
125
  for (const Point* p : poly.outer) {
126
126
  if (p) {
127
- new_res->cloned_points_storage.push_back(std::make_unique<Point>(p->x, p->y));
128
- new_poly.outer.push_back(new_res->cloned_points_storage.back().get());
127
+ new_res->cloned_points_storage.push_back(Point(p->x, p->y));
128
+ size_t idx = new_res->cloned_points_storage.size() - 1;
129
+ new_poly.outer.push_back(&new_res->cloned_points_storage[idx]);
129
130
  }
130
131
  }
131
132
  // inner
132
133
  for (const auto& seq : poly.inner) {
133
134
  std::vector<Point*> new_seq;
135
+ new_seq.reserve(seq.size());
134
136
  for (const Point* p : seq) {
135
137
  if (p) {
136
- new_res->cloned_points_storage.push_back(std::make_unique<Point>(p->x, p->y));
137
- new_seq.push_back(new_res->cloned_points_storage.back().get());
138
+ new_res->cloned_points_storage.push_back(Point(p->x, p->y));
139
+ size_t idx = new_res->cloned_points_storage.size() - 1;
140
+ new_seq.push_back(&new_res->cloned_points_storage[idx]);
138
141
  }
139
142
  }
140
143
  new_poly.inner.push_back(new_seq);
@@ -1,3 +1,3 @@
1
1
  module Contrek
2
- VERSION = "1.2.4"
2
+ VERSION = "1.2.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contrek
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuele Cesaroni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-05-26 00:00:00.000000000 Z
11
+ date: 2026-05-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec