contrek 1.0.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 (78) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.rspec +3 -0
  4. data/Gemfile +3 -0
  5. data/Gemfile.lock +84 -0
  6. data/LICENSE.md +9 -0
  7. data/README.md +118 -0
  8. data/Rakefile +19 -0
  9. data/contrek.gemspec +23 -0
  10. data/contrek.png +0 -0
  11. data/ext/cpp_polygon_finder/PolygonFinder/.cproject +136 -0
  12. data/ext/cpp_polygon_finder/PolygonFinder/.project +27 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/.settings/org.eclipse.ltk.core.refactoring.prefs +2 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/images/labyrinth.png +0 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/Main.cpp +41 -0
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +69 -0
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.h +19 -0
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.cpp +52 -0
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/Bitmap.h +32 -0
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp +656 -0
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h +42 -0
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp +48 -0
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/PngBitmap.h +32 -0
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp +30 -0
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h +26 -0
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/X_picopng.cpp +576 -0
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp +120 -0
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.h +40 -0
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.cpp +36 -0
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Lists.h +30 -0
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +111 -0
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +80 -0
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +325 -0
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +59 -0
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +206 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +69 -0
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/optionparser.h +2858 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.cpp +23 -0
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/Matcher.h +23 -0
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.cpp +20 -0
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBMatcher.h +23 -0
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp +20 -0
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/RGBNotMatcher.h +23 -0
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp +20 -0
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/matchers/ValueNotMatcher.h +21 -0
  46. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +40 -0
  47. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +23 -0
  48. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +19 -0
  49. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +25 -0
  50. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +30 -0
  51. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +21 -0
  52. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +50 -0
  53. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +121 -0
  54. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +260 -0
  55. data/ext/cpp_polygon_finder/extconf.rb +2 -0
  56. data/lib/contrek/bitmaps/bitmap.rb +21 -0
  57. data/lib/contrek/bitmaps/chunky_bitmap.rb +33 -0
  58. data/lib/contrek/bitmaps/painting.rb +40 -0
  59. data/lib/contrek/bitmaps/png_bitmap.rb +62 -0
  60. data/lib/contrek/bitmaps/rgb_color.rb +25 -0
  61. data/lib/contrek/finder/list.rb +132 -0
  62. data/lib/contrek/finder/list_entry.rb +11 -0
  63. data/lib/contrek/finder/listable.rb +8 -0
  64. data/lib/contrek/finder/lists.rb +25 -0
  65. data/lib/contrek/finder/node.rb +126 -0
  66. data/lib/contrek/finder/node_cluster.rb +294 -0
  67. data/lib/contrek/finder/polygon_finder.rb +121 -0
  68. data/lib/contrek/map/mercator_projection.rb +76 -0
  69. data/lib/contrek/matchers/matcher.rb +20 -0
  70. data/lib/contrek/matchers/matcher_hsb.rb +24 -0
  71. data/lib/contrek/matchers/value_not_matcher.rb +9 -0
  72. data/lib/contrek/reducers/linear_reducer.rb +25 -0
  73. data/lib/contrek/reducers/reducer.rb +14 -0
  74. data/lib/contrek/reducers/uniq_reducer.rb +9 -0
  75. data/lib/contrek/reducers/visvalingam_reducer.rb +139 -0
  76. data/lib/contrek/version.rb +3 -0
  77. data/lib/contrek.rb +58 -0
  78. metadata +175 -0
@@ -0,0 +1,260 @@
1
+ /*
2
+ * cpp_polygon_finder.cpp
3
+ *
4
+ * Created on: 25 apr 2025
5
+ * Author: ema
6
+ * Copyright 2025 Emanuele Cesaroni
7
+ */
8
+ // https://github.com/mapnik/Ruby-Mapnik/blob/master/ext/ruby_mapnik/_mapnik_map.rb.cpp
9
+
10
+ #include <iostream>
11
+ #include <list>
12
+ #include <rice/rice.hpp>
13
+ #include <rice/stl.hpp>
14
+ #include <vector>
15
+ #include <map>
16
+ #include <string>
17
+
18
+ #include "PolygonFinder/src/polygon/finder/PolygonFinder.h"
19
+ #include "PolygonFinder/src/polygon/finder/PolygonFinder.cpp"
20
+ #include "PolygonFinder/src/polygon/finder/NodeCluster.cpp"
21
+ #include "PolygonFinder/src/polygon/finder/NodeCluster.h"
22
+ #include "PolygonFinder/src/polygon/finder/Node.cpp"
23
+ #include "PolygonFinder/src/polygon/finder/Node.h"
24
+ #include "PolygonFinder/src/polygon/finder/List.cpp"
25
+ #include "PolygonFinder/src/polygon/finder/List.h"
26
+ #include "PolygonFinder/src/polygon/finder/Lists.cpp"
27
+ #include "PolygonFinder/src/polygon/finder/Lists.h"
28
+ #include "PolygonFinder/src/polygon/bitmaps/Bitmap.h"
29
+ #include "PolygonFinder/src/polygon/bitmaps/Bitmap.cpp"
30
+ #include "PolygonFinder/src/polygon/bitmaps/PngBitmap.h"
31
+ #include "PolygonFinder/src/polygon/bitmaps/PngBitmap.cpp"
32
+ #include "PolygonFinder/src/polygon/bitmaps/FastPngBitmap.h"
33
+ #include "PolygonFinder/src/polygon/bitmaps/FastPngBitmap.cpp"
34
+ #include "PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h"
35
+ #include "PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.cpp"
36
+ #include "PolygonFinder/src/polygon/matchers/Matcher.h"
37
+ #include "PolygonFinder/src/polygon/matchers/Matcher.cpp"
38
+ #include "PolygonFinder/src/polygon/matchers/ValueNotMatcher.h"
39
+ #include "PolygonFinder/src/polygon/matchers/ValueNotMatcher.cpp"
40
+ #include "PolygonFinder/src/polygon/matchers/RGBMatcher.h"
41
+ #include "PolygonFinder/src/polygon/matchers/RGBMatcher.cpp"
42
+ #include "PolygonFinder/src/polygon/matchers/RGBNotMatcher.h"
43
+ #include "PolygonFinder/src/polygon/matchers/RGBNotMatcher.cpp"
44
+ #include "PolygonFinder/src/polygon/reducers/Reducer.cpp"
45
+ #include "PolygonFinder/src/polygon/reducers/Reducer.h"
46
+ #include "PolygonFinder/src/polygon/reducers/UniqReducer.cpp"
47
+ #include "PolygonFinder/src/polygon/reducers/UniqReducer.h"
48
+ #include "PolygonFinder/src/polygon/reducers/LinearReducer.cpp"
49
+ #include "PolygonFinder/src/polygon/reducers/LinearReducer.h"
50
+ #include "PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp"
51
+ #include "PolygonFinder/src/polygon/reducers/VisvalingamReducer.h"
52
+ #include "png++/png.hpp"
53
+
54
+ using namespace Rice;
55
+
56
+ namespace Rice::detail
57
+ { template<>
58
+ class To_Ruby<std::list<Point*> >
59
+ { public:
60
+ VALUE convert(std::list<Point*> const & x)
61
+ { return Rice::Array(x.begin(), x.end());
62
+ }
63
+ };
64
+
65
+ template<>
66
+ class To_Ruby<std::list<std::list<Point*>>>
67
+ { public:
68
+ VALUE convert(std::list<std::list<Point*>> const & x)
69
+ { return Rice::Array(x.begin(), x.end());
70
+ }
71
+ };
72
+
73
+ template<>
74
+ class To_Ruby<std::list<Point*>*>
75
+ { public:
76
+ VALUE convert(std::list<Point*>* const & x)
77
+ { return Rice::Array(x->begin(), x->end());
78
+ }
79
+ };
80
+
81
+ template<>
82
+ class To_Ruby<std::list<std::list<Point*>*>>
83
+ { public:
84
+ VALUE convert(std::list<std::list<Point*>*> const & x)
85
+ { return Rice::Array(x.begin(), x.end());
86
+ }
87
+ };
88
+
89
+ template<>
90
+ class To_Ruby<Point*>
91
+ { public:
92
+ VALUE convert(Point* const & x)
93
+ { Rice::Hash h = Rice::Hash();
94
+ h[Symbol("x")] = x->x;
95
+ h[Symbol("y")] = x->y;
96
+ return(h);
97
+ }
98
+ };
99
+
100
+ template<>
101
+ class To_Ruby<std::map<std::string, double>*>
102
+ { public:
103
+ VALUE convert(std::map<std::string, double>* const & x)
104
+ { Rice::Hash return_me = Rice::Hash();
105
+ std::map<std::string, double>::iterator it;
106
+ for ( it = x->begin(); it != x->end(); it++ )
107
+ { return_me[String(it->first)] = it->second;
108
+ }
109
+ return return_me;
110
+ }
111
+ };
112
+
113
+ template<>
114
+ class From_Ruby<std::vector<std::string>*>
115
+ { public:
116
+ Convertible is_convertible(VALUE value)
117
+ { switch (rb_type(value))
118
+ { case RUBY_T_HASH:
119
+ return Convertible::Cast;
120
+ break;
121
+ default:
122
+ return Convertible::None;
123
+ }
124
+ }
125
+ std::vector<std::string>* convert(VALUE value)
126
+ { std::vector<std::string> *arguments = new std::vector<std::string>();
127
+ if (rb_type(value) == RUBY_T_NIL) return(arguments);
128
+ Rice::Hash hash = (Rice::Hash) value;
129
+ for (Rice::Hash::iterator it = hash.begin(); it != hash.end(); ++it) {
130
+ Rice::String keyString = it->key.to_s();
131
+ Rice::Object value = it->value;
132
+ switch (value.rb_type()) {
133
+ case T_STRING:
134
+ arguments->push_back("--" + keyString.str()+"="+((Rice::String) value).str());
135
+ break;
136
+ case T_SYMBOL:
137
+ arguments->push_back("--" + keyString.str()+"="+((Rice::Symbol) value).str());
138
+ break;
139
+ case T_FLOAT:
140
+ arguments->push_back("--" + keyString.str()+"="+std::to_string(NUM2DBL(value.value())));
141
+ break;
142
+ case T_FIXNUM:
143
+ arguments->push_back("--" + keyString.str()+"="+std::to_string(NUM2INT(value.value())));
144
+ break;
145
+ case T_TRUE:
146
+ arguments->push_back("--" + keyString.str()+"=true");
147
+ break;
148
+ case T_FALSE:
149
+ arguments->push_back("--" + keyString.str()+"=false");
150
+ break;
151
+ case T_HASH:
152
+ std::vector<std::string>* iv = From_Ruby<std::vector<std::string>*>::convert(value);
153
+ for (std::vector<std::string>::iterator it_iv = iv->begin() ; it_iv != iv->end(); ++it_iv)
154
+ { (*it_iv).replace(0, 2, "_");
155
+ arguments->push_back("--" + keyString.str() + *it_iv);
156
+ }
157
+ break;
158
+ }
159
+ }
160
+ return arguments;
161
+ }
162
+ };
163
+
164
+ template<>
165
+ struct Type<ProcessResult>
166
+ { static bool verify()
167
+ { return true;
168
+ }
169
+ };
170
+
171
+ template<>
172
+ class To_Ruby<ProcessResult*>
173
+ { public:
174
+ VALUE convert(ProcessResult* const & pr)
175
+ { Rice::Hash return_me = Rice::Hash();
176
+ return_me[Symbol("benchmarks")] = &pr->benchmarks;
177
+ return_me[Symbol("groups")] = pr->groups;
178
+ return_me[Symbol("named_sequence")] = pr->named_sequence;
179
+ Rice::Array out;
180
+ for (std::list<std::map<std::string, std::list<std::list<Point*>*>>>::iterator x = pr->polygons.begin(); x != pr->polygons.end(); ++x)
181
+ { Rice::Hash h = Rice::Hash();
182
+ h[Symbol("outer")] = (*x)["outer"].front();
183
+ h[Symbol("inner")] = (*x)["inner"];
184
+ out.push(h);
185
+ }
186
+ return_me[Symbol("polygons")] = out;
187
+ Rice::Array tmapout;
188
+ for (std::list<int*>::iterator tm = pr->treemap.begin(); tm != pr->treemap.end(); ++tm)
189
+ { Rice::Array tmentry;
190
+ tmentry.push((*tm)[0]);
191
+ tmentry.push((*tm)[1]);
192
+ tmapout.push(tmentry);
193
+ }
194
+ return_me[Symbol("treemap")] = tmapout;
195
+ return(return_me);
196
+ }
197
+ };
198
+ } // namespace Rice::detail
199
+
200
+ extern "C"
201
+ void Init_cpp_polygon_finder() {
202
+ Data_Type<Bitmap> rb_cBitmap =
203
+ define_class<Bitmap>("CPPBitMap")
204
+ .define_constructor(Constructor<Bitmap, std::string, int>())
205
+ .define_method("value_set", &Bitmap::value_set)
206
+ .define_method("value_at", &Bitmap::value_at)
207
+ .define_method("w", &Bitmap::w)
208
+ .define_method("h", &Bitmap::h)
209
+ .define_method("error", &Bitmap::error)
210
+ .define_method("clear", &Bitmap::clear)
211
+ .define_method("print", &Bitmap::print);
212
+
213
+ Data_Type<RemoteFastPngBitmap> rb_cRemotePngBitmap =
214
+ define_class<RemoteFastPngBitmap, Bitmap>("CPPRemotePngBitMap")
215
+ .define_constructor(Constructor<RemoteFastPngBitmap, std::string*>(), Arg("url"))
216
+ .define_method("value_set", &FastPngBitmap::value_set)
217
+ .define_method("value_at", &FastPngBitmap::value_at)
218
+ .define_method("rgb_value_at", &FastPngBitmap::rgb_value_at)
219
+ .define_method("w", &FastPngBitmap::w)
220
+ .define_method("h", &FastPngBitmap::h)
221
+ .define_method("error", &FastPngBitmap::error)
222
+ .define_method("print", &FastPngBitmap::print);
223
+
224
+ Data_Type<FastPngBitmap> rb_cPngBitmap =
225
+ define_class<FastPngBitmap, Bitmap>("CPPPngBitMap")
226
+ .define_constructor(Constructor<FastPngBitmap, std::string>(), Arg("filename"))
227
+ .define_method("value_set", &FastPngBitmap::value_set)
228
+ .define_method("value_at", &FastPngBitmap::value_at)
229
+ .define_method("rgb_value_at", &FastPngBitmap::rgb_value_at)
230
+ .define_method("w", &FastPngBitmap::w)
231
+ .define_method("h", &FastPngBitmap::h)
232
+ .define_method("error", &FastPngBitmap::error)
233
+ .define_method("print", &FastPngBitmap::print);
234
+
235
+ Data_Type<Matcher> rb_cMatcher =
236
+ define_class<Matcher>("CPPMatcher")
237
+ .define_constructor(Constructor<Matcher, char>())
238
+ .define_method("match", &Matcher::match);
239
+
240
+ Data_Type<ValueNotMatcher> rb_cValueNotMatcher =
241
+ define_class<ValueNotMatcher, Matcher>("CPPValueNotMatcher")
242
+ .define_constructor(Constructor<ValueNotMatcher, char>())
243
+ .define_method("match", &ValueNotMatcher::match);
244
+
245
+ Data_Type<RGBMatcher> rb_cRGBMatcher =
246
+ define_class<RGBMatcher, Matcher>("CPPRGBMatcher")
247
+ .define_constructor(Constructor<RGBMatcher, unsigned int>())
248
+ .define_method("match", &RGBMatcher::match);
249
+
250
+ Data_Type<RGBNotMatcher> rb_cRGBNotMatcher =
251
+ define_class<RGBNotMatcher, Matcher>("CPPRGBNotMatcher")
252
+ .define_constructor(Constructor<RGBNotMatcher, int>())
253
+ .define_method("match", &RGBNotMatcher::match);
254
+
255
+ Data_Type<PolygonFinder> rb_cPolygonFinder =
256
+ define_class<PolygonFinder>("CPPPolygonFinder")
257
+ .define_constructor(Constructor<PolygonFinder, Bitmap*, Matcher*, Bitmap*, std::vector<std::string>*>(), Arg("bitmap"), Arg("matcher"), Arg("test_bitmap") = nullptr, Arg("options") = nullptr)
258
+ .define_method("get_shapelines", &PolygonFinder::get_shapelines)
259
+ .define_method("process_info", &PolygonFinder::process_info);
260
+ }
@@ -0,0 +1,2 @@
1
+ require "mkmf-rice"
2
+ create_makefile "cpp_polygon_finder"
@@ -0,0 +1,21 @@
1
+ module Contrek
2
+ module Bitmaps
3
+ class Bitmap
4
+ include Painting
5
+
6
+ def scan
7
+ x = 0
8
+ y = 0
9
+ loop do
10
+ yield x, y, value_at(x, y)
11
+ x += 1
12
+ if x == w
13
+ x = 0
14
+ y += 1
15
+ break if y == h
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ module Contrek
2
+ module Bitmaps
3
+ class ChunkyBitmap < Bitmap
4
+ def initialize(data, mod)
5
+ @raw = data.dup
6
+ @module = mod
7
+ end
8
+
9
+ def clear(val = "0")
10
+ @raw = val * @module * h
11
+ end
12
+
13
+ def w
14
+ @module
15
+ end
16
+
17
+ def h
18
+ @raw.size / @module
19
+ end
20
+
21
+ def value_at(x, y)
22
+ @raw[y * @module + x]
23
+ end
24
+
25
+ def value_set(x, y, value)
26
+ return if y >= h
27
+ return if x >= w
28
+
29
+ @raw[y * @module + x] = value
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ module Contrek
2
+ module Bitmaps
3
+ module Painting
4
+ def draw_line(start_x, start_y, end_x, end_y, value)
5
+ raise NoMethodError
6
+ end
7
+
8
+ def bitmap_colors(step: 1, max: 0)
9
+ colors = {}
10
+ step = 1 if step <= 0
11
+ 0.step(h - 1, step) do |h|
12
+ 0.step(w - 1, step) do |w|
13
+ color = value_at(w, h)
14
+ colors[color] ||= 0
15
+ colors[color] += 1
16
+ break if colors.size == max
17
+ end
18
+ end
19
+ colors.sort_by { |color, count| -color }
20
+ end
21
+
22
+ def self.direct_draw_polygons(polygons, png_image)
23
+ polygons.compact.each do |poly|
24
+ color = ChunkyPNG::Color("red @ 1.0")
25
+ poly[:outer].each_cons(2) do |coords|
26
+ png_image.draw_line(coords[0][:x], coords[0][:y], coords[1][:x], coords[1][:y], color)
27
+ end
28
+ png_image.draw_line(poly[:outer][0][:x], poly[:outer][0][:y], poly[:outer][-1][:x], poly[:outer][-1][:y], color)
29
+ color = ChunkyPNG::Color("green @ 1.0")
30
+ poly[:inner].each do |sequence|
31
+ sequence.each_cons(2) do |coords|
32
+ png_image.draw_line(coords[0][:x], coords[0][:y], coords[1][:x], coords[1][:y], color)
33
+ end
34
+ png_image.draw_line(sequence[0][:x], sequence[0][:y], sequence[-1][:x], sequence[-1][:y], color)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,62 @@
1
+ require "chunky_png"
2
+
3
+ module Contrek
4
+ module Bitmaps
5
+ class PngBitmap < Bitmap
6
+ def initialize(file_path)
7
+ @image = ChunkyPNG::Image.from_file(file_path)
8
+ end
9
+
10
+ def w
11
+ @image.dimension.width
12
+ end
13
+
14
+ def h
15
+ @image.dimension.height
16
+ end
17
+
18
+ def draw_line(start_x, start_y, end_x, end_y, value)
19
+ @image.line_xiaolin_wu(start_x, start_y, end_x, end_y, value)
20
+ end
21
+
22
+ def value_at(x, y)
23
+ @image[x, y]
24
+ end
25
+
26
+ def rgb_value_at(x, y)
27
+ value_at(x, y)
28
+ end
29
+
30
+ def hsv_at(x, y)
31
+ @image.get_pixel(x, y).to_hsv
32
+ end
33
+
34
+ def value_set(x, y, value)
35
+ @image[x, y] = value
36
+ end
37
+
38
+ def save(filename)
39
+ @image.save(filename, interlace: true, compression: Zlib::NO_COMPRESSION)
40
+ end
41
+
42
+ def to_tmp_file
43
+ tmp_png_file = Tempfile.new
44
+ tmp_png_file.binmode
45
+ tmp_png_file.write(@image.to_blob)
46
+ tmp_png_file
47
+ end
48
+
49
+ def resize_h(new_h)
50
+ old_w = w
51
+ old_h = h
52
+
53
+ new_w = (old_w * new_h) / old_h
54
+ @image = @image.resize(new_w, new_h)
55
+ end
56
+
57
+ def inspect
58
+ "PngBitMap"
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,25 @@
1
+ module Contrek
2
+ module Bitmaps
3
+ class RgbColor
4
+ attr_reader :raw
5
+ def initialize(r:, g:, b:, a: 255)
6
+ @r = r
7
+ @g = g
8
+ @b = b
9
+ @a = a
10
+ @raw = (r << 24) + (g << 16) + (b << 8) + a
11
+ end
12
+
13
+ def to_rgb_raw
14
+ @raw >> 8
15
+ end
16
+
17
+ def self.reverse_raw(raw)
18
+ [:a, :b, :g, :r].each_with_object({}) do |c, h|
19
+ h[c] = raw & 0xFF
20
+ raw >>= 8
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,132 @@
1
+ module Contrek
2
+ module Finder
3
+ class List
4
+ attr_reader :start, :end, :size, :idd
5
+ def initialize(id)
6
+ @start = nil
7
+ @end = nil
8
+ @size = 0
9
+ @idd = id
10
+ end
11
+
12
+ def first
13
+ @start
14
+ end
15
+
16
+ def find
17
+ each { |e| return e if yield(e) }
18
+ nil
19
+ end
20
+
21
+ def contains(entry)
22
+ entry.data_pointer[@idd].inside
23
+ end
24
+
25
+ def grab(source_list)
26
+ return if source_list.size == 0
27
+
28
+ source_list_idd = source_list.idd
29
+ source_list_start_entry = source_list.start
30
+
31
+ act = source_list.end
32
+ loop do
33
+ break if (act = act.data_pointer[source_list_idd].prev).nil?
34
+ end
35
+
36
+ source_entry = source_list.start
37
+ loop do
38
+ source_entry.data_pointer[@idd] = source_entry.data_pointer[source_list_idd]
39
+ next_entry = source_entry.data_pointer[source_list_idd].next
40
+ source_entry.data_pointer[source_list_idd] = Contrek::Finder::Lists::Link.new(nil, nil, false)
41
+ break if next_entry.nil?
42
+ source_entry = next_entry
43
+ end
44
+
45
+ source_list_start_entry.data_pointer[@idd].prev = @end
46
+ @end.data_pointer[@idd].next = source_list_start_entry unless @end.nil?
47
+
48
+ @end = source_list.end
49
+ @start = source_list.start if @start.nil?
50
+ @size += source_list.size
51
+
52
+ source_list.reset
53
+ end
54
+
55
+ def reset
56
+ @end = nil
57
+ @start = nil
58
+ @size = 0
59
+ end
60
+
61
+ def <<(entry)
62
+ return if entry.data_pointer[@idd].inside == true
63
+
64
+ if @size > 0
65
+ @end.data_pointer[@idd].next = entry
66
+ entry.data_pointer[@idd].prev = @end
67
+ else
68
+ @start = entry
69
+ end
70
+ @end = entry
71
+ entry.data_pointer[@idd].inside = true
72
+ @size += 1
73
+ end
74
+
75
+ def shift
76
+ return nil if @size == 0
77
+ retme = @start
78
+ next_of_retme = retme.data_pointer[@idd].next
79
+ @start = next_of_retme
80
+
81
+ @end = nil if retme == @end
82
+
83
+ next_of_retme.data_pointer[@idd].prev = nil unless next_of_retme.nil?
84
+ @size -= 1
85
+
86
+ retme.data_pointer[@idd].next = nil
87
+ retme.data_pointer[@idd].prev = nil
88
+ retme.data_pointer[@idd].inside = false
89
+ retme
90
+ end
91
+
92
+ def each
93
+ return if @size == 0
94
+ act = @start
95
+ loop do
96
+ yield act
97
+ break if (act = act.data_pointer[@idd].next).nil?
98
+ end
99
+ end
100
+
101
+ def map
102
+ ary = []
103
+ each { |e| ary << yield(e) }
104
+ ary
105
+ end
106
+
107
+ def delete(entry)
108
+ return if @size == 0
109
+ return if entry.data_pointer[@idd].inside == false
110
+
111
+ next_of_entry = entry.data_pointer[@idd].next
112
+ prev_of_entry = entry.data_pointer[@idd].prev
113
+
114
+ case entry
115
+ when @start
116
+ @start = next_of_entry
117
+ when @end
118
+ @end = prev_of_entry
119
+ end
120
+
121
+ next_of_entry.data_pointer[@idd].prev = prev_of_entry unless next_of_entry.nil?
122
+ prev_of_entry.data_pointer[@idd].next = next_of_entry unless prev_of_entry.nil?
123
+
124
+ entry.data_pointer[@idd].next = nil
125
+ entry.data_pointer[@idd].prev = nil
126
+
127
+ @size -= 1
128
+ entry.data_pointer[@idd].inside = false
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,11 @@
1
+ module Contrek
2
+ module Finder
3
+ class ListEntry
4
+ attr_reader :data_pointer, :name
5
+ def initialize(lists, name)
6
+ @data_pointer = lists.get_data_pointer
7
+ @name = name
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,8 @@
1
+ module Contrek
2
+ module Finder
3
+ module Listable
4
+ attr_accessor :data_pointer
5
+ @data_pointer
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ module Contrek
2
+ module Finder
3
+ class Lists
4
+ Link = Struct.new(:next, :prev, :inside)
5
+ def initialize
6
+ @lists = []
7
+ end
8
+
9
+ def get_data_pointer
10
+ data_pointer = Array.new(@lists.size) { [] }
11
+ @lists.size.times do |n|
12
+ data_pointer[n] = Link.new(nil, nil, false)
13
+ end
14
+
15
+ data_pointer
16
+ end
17
+
18
+ def add_list
19
+ list = Contrek::Finder::List.new(@lists.size)
20
+ @lists << list
21
+ list
22
+ end
23
+ end
24
+ end
25
+ end