contrek 1.4.1 → 1.4.2

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/Gemfile.lock +4 -1
  4. data/README.md +207 -36
  5. data/contrek.gemspec +1 -0
  6. data/ext/cpp_polygon_finder/PolygonFinder/src/ContrekApi.h +2 -2
  7. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +53 -144
  8. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RawBitmap.cpp +14 -2
  9. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RawBitmap.h +1 -0
  10. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/AsciiSource.cpp +69 -0
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/AsciiSource.h +34 -0
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/PngSource.cpp +108 -0
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/PngSource.h +40 -0
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/RasterSource.h +22 -0
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/RasterStreamer.h +92 -0
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp +6 -8
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +7 -2
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +3 -1
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.cpp +6 -0
  20. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +46 -0
  21. data/lib/contrek/bitmaps/bitmap.rb +2 -2
  22. data/lib/contrek/bitmaps/chunky_bitmap.rb +23 -8
  23. data/lib/contrek/bitmaps/png_bitmap.rb +4 -0
  24. data/lib/contrek/bitmaps/rgba_bitmap.rb +50 -0
  25. data/lib/contrek/bitmaps/streaming/raster_streamer.rb +66 -0
  26. data/lib/contrek/bitmaps/streaming/sources/ascii.rb +33 -0
  27. data/lib/contrek/bitmaps/streaming/sources/base.rb +27 -0
  28. data/lib/contrek/bitmaps/streaming/sources/png.rb +105 -0
  29. data/lib/contrek/finder/concurrent/finder.rb +3 -2
  30. data/lib/contrek/finder/polygon_finder.rb +6 -3
  31. data/lib/contrek/version.rb +1 -1
  32. data/lib/contrek.rb +5 -0
  33. metadata +26 -1
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module Contrek
6
+ module Bitmaps
7
+ class RgbaBitmap < Bitmap
8
+ BYTES_PER_PIXEL = 4
9
+
10
+ def initialize(width, height)
11
+ @width = width
12
+ @height = height
13
+ @raw = FFI::MemoryPointer.new(:uint8, @width * @height * BYTES_PER_PIXEL)
14
+ end
15
+
16
+ def w
17
+ @width
18
+ end
19
+
20
+ def h
21
+ @height
22
+ end
23
+
24
+ def get_bytes_per_pixel
25
+ BYTES_PER_PIXEL
26
+ end
27
+
28
+ def value_at(x, y)
29
+ rgb_value_at(x, y)
30
+ end
31
+
32
+ def get_row_ptr(y)
33
+ @raw + (y * @width * BYTES_PER_PIXEL)
34
+ end
35
+
36
+ def rgb_value_at(x, y)
37
+ index = (y * @width + x) * BYTES_PER_PIXEL
38
+ r = @raw.get_uint8(index)
39
+ g = @raw.get_uint8(index + 1)
40
+ b = @raw.get_uint8(index + 2)
41
+ a = @raw.get_uint8(index + 3)
42
+ r | (g << 8) | (b << 16) | (a << 24)
43
+ end
44
+
45
+ def read_bytes(size)
46
+ @raw.read_bytes(size)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+
5
+ module Contrek
6
+ module Bitmaps
7
+ module Streaming
8
+ class RasterStreamer
9
+ OVERLAP = 1
10
+
11
+ attr_reader :stripe_height
12
+
13
+ def initialize(source, stripe_height:)
14
+ @source = source
15
+ @stripe_height = stripe_height
16
+
17
+ raise ArgumentError, "stripe_height must be greater than 1" if @stripe_height <= OVERLAP
18
+ end
19
+
20
+ def each(buffer)
21
+ return enum_for(:each, buffer) unless block_given?
22
+
23
+ width = @source.width
24
+ height = @source.height
25
+ bytes_per_pixel = @source.get_bytes_per_pixel
26
+
27
+ row_size = width * bytes_per_pixel
28
+
29
+ source_row = 0
30
+ buffer_rows = 0
31
+ first_stripe = true
32
+
33
+ while source_row < height
34
+ unless first_stripe
35
+ previous_last_row = buffer.get_row_ptr(buffer_rows - 1)
36
+ current_first_row = buffer.get_row_ptr(0)
37
+ current_first_row.put_bytes(0, previous_last_row.read_bytes(row_size))
38
+ end
39
+
40
+ overlap_rows = first_stripe ? 0 : OVERLAP
41
+ available_rows = @stripe_height - overlap_rows
42
+ remaining_rows = height - source_row
43
+ rows_to_read = [available_rows, remaining_rows].min
44
+
45
+ rows_read = 0
46
+ rows_to_read.times do |i|
47
+ buffer_y = overlap_rows + i
48
+ row_ptr = buffer.get_row_ptr(buffer_y)
49
+ break unless @source.read_next_row(row_ptr, row_size)
50
+
51
+ source_row += 1
52
+ rows_read += 1
53
+ end
54
+
55
+ buffer_rows = overlap_rows + rows_read
56
+ break if buffer_rows == 0
57
+
58
+ yield buffer, buffer_rows, buffer_rows * row_size
59
+
60
+ first_stripe = false
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Contrek
6
+ module Bitmaps
7
+ module Streaming
8
+ module Sources
9
+ class Ascii < Base
10
+ extend Forwardable
11
+
12
+ def_delegator :@bitmap, :w, :width
13
+ def_delegator :@bitmap, :h, :height
14
+ def_delegators :@bitmap, :get_bytes_per_pixel
15
+
16
+ def initialize(bitmap)
17
+ @current_row = 0
18
+ @bitmap = bitmap
19
+ end
20
+
21
+ def read_next_row(destination, row_size)
22
+ return false if @current_row >= height
23
+
24
+ row = @bitmap.get_row_ptr(@current_row)
25
+ destination.put_bytes(0, row.read_bytes(row_size))
26
+ @current_row += 1
27
+ true
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Contrek
4
+ module Bitmaps
5
+ module Streaming
6
+ module Sources
7
+ class Base
8
+ def width
9
+ raise NotImplementedError
10
+ end
11
+
12
+ def height
13
+ raise NotImplementedError
14
+ end
15
+
16
+ def get_bytes_per_pixel
17
+ raise NotImplementedError
18
+ end
19
+
20
+ def read_next_row(destination, row_size)
21
+ raise NotImplementedError
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ffi"
4
+ require "cpp_polygon_finder"
5
+
6
+ module Contrek
7
+ module Bitmaps
8
+ module Streaming
9
+ module Sources
10
+ class Png
11
+ attr_reader :width, :height
12
+
13
+ module LibSpng
14
+ extend FFI::Library
15
+
16
+ ffi_lib FFI::Library::CURRENT_PROCESS
17
+
18
+ SPNG_FMT_RGBA8 = 1
19
+ SPNG_DECODE_PROGRESSIVE = 256
20
+ SPNG_EOI = 75
21
+
22
+ class Ihdr < FFI::Struct
23
+ layout(
24
+ :width, :uint32,
25
+ :height, :uint32,
26
+ :bit_depth, :uint8,
27
+ :color_type, :uint8,
28
+ :compression_method, :uint8,
29
+ :filter_method, :uint8,
30
+ :interlace_method, :uint8
31
+ )
32
+ end
33
+
34
+ attach_function :spng_ctx_new, [:int], :pointer
35
+ attach_function :spng_ctx_free, [:pointer], :void
36
+ attach_function :spng_set_png_file, [:pointer, :pointer], :int
37
+ attach_function :spng_get_ihdr, [:pointer, :pointer], :int
38
+ attach_function :spng_decode_image, [:pointer, :pointer, :size_t, :int, :int], :int
39
+ attach_function :spng_decode_row, [:pointer, :pointer, :size_t], :int
40
+ end
41
+
42
+ module LibC
43
+ extend FFI::Library
44
+
45
+ ffi_lib FFI::Library::LIBC
46
+
47
+ attach_function :fopen, [:string, :string], :pointer
48
+ attach_function :fclose, [:pointer], :int
49
+ end
50
+
51
+ def initialize(filepath)
52
+ @fp = LibC.fopen(filepath, "rb")
53
+ raise "Unable to open PNG: #{filepath}" if @fp.null?
54
+
55
+ @ctx = LibSpng.spng_ctx_new(0)
56
+ raise "Unable to create spng context" if @ctx.null?
57
+
58
+ ret = LibSpng.spng_set_png_file(@ctx, @fp)
59
+ raise "spng_set_png_file failed: #{ret}" unless ret == 0
60
+
61
+ ihdr = LibSpng::Ihdr.new
62
+
63
+ ret = LibSpng.spng_get_ihdr(@ctx, ihdr)
64
+ raise "spng_get_ihdr failed: #{ret}" unless ret == 0
65
+
66
+ @width = ihdr[:width]
67
+ @height = ihdr[:height]
68
+
69
+ ret = LibSpng.spng_decode_image(
70
+ @ctx,
71
+ nil,
72
+ 0,
73
+ LibSpng::SPNG_FMT_RGBA8,
74
+ LibSpng::SPNG_DECODE_PROGRESSIVE
75
+ )
76
+ raise "Unable to initialize progressive decoding: #{ret}" unless ret == 0
77
+ end
78
+
79
+ def get_bytes_per_pixel
80
+ 4
81
+ end
82
+
83
+ def read_next_row(destination, row_size)
84
+ ret = LibSpng.spng_decode_row(@ctx, destination, row_size)
85
+ unless ret == 0 || ret == LibSpng::SPNG_EOI
86
+ raise "spng_decode_row failed: #{ret}"
87
+ end
88
+ true
89
+ end
90
+
91
+ def close
92
+ unless @ctx.nil? || @ctx.null?
93
+ LibSpng.spng_ctx_free(@ctx)
94
+ @ctx = nil
95
+ end
96
+ unless @fp.nil? || @fp.null?
97
+ LibC.fclose(@fp)
98
+ @fp = nil
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -30,7 +30,7 @@ module Contrek
30
30
  @options = options
31
31
  @clusters = []
32
32
  @maximum_width = bitmap.w
33
- @height = bitmap.h
33
+ @height = options[:processing_height] || bitmap.h
34
34
  @number_of_tiles = options[:number_of_tiles] || (raise "number_of_tiles params is needed!")
35
35
  @number_of_tiles = 1 if @number_of_tiles <= 0
36
36
 
@@ -51,6 +51,7 @@ module Contrek
51
51
  bitmap: bitmap,
52
52
  matcher: matcher,
53
53
  options: {
54
+ processing_height: @options[:processing_height],
54
55
  versus: current_versus,
55
56
  bounds: true,
56
57
  treemap: @options[:treemap],
@@ -71,7 +72,7 @@ module Contrek
71
72
 
72
73
  x = tile_end_x - 1
73
74
  end
74
- process_tiles!(bitmap, height: bitmap.h, deterministic: @options[:deterministic])
75
+ process_tiles!(bitmap, height: @height, deterministic: @options[:deterministic])
75
76
  end.real
76
77
  end
77
78
 
@@ -10,10 +10,13 @@ module Contrek
10
10
  @options = {versus: :a}.merge(options)
11
11
  sanitize_options
12
12
  @source_bitmap = bitmap
13
+ @processing_height = (options[:processing_height] || bitmap.h).abs
14
+ raise ArgumentError, "Option processing_height must be less or equal than image height!" if @processing_height > bitmap.h
15
+
13
16
  @matcher = matcher
14
17
 
15
18
  @test_bitmap = test_bitmap
16
- @node_cluster = NodeCluster.new(@source_bitmap.h, @options)
19
+ @node_cluster = NodeCluster.new(@processing_height, @options)
17
20
  @reports = {}
18
21
 
19
22
  # 1 finds matching blocks
@@ -51,7 +54,7 @@ module Contrek
51
54
  groups_names: @node_cluster.root_nodes.map(&:name).join,
52
55
  benchmarks: format_benchmarks,
53
56
  width: @source_bitmap.w,
54
- height: @source_bitmap.h,
57
+ height: @processing_height,
55
58
  treemap: (@node_cluster.treemap if @options.has_key?(:treemap)),
56
59
  options: @ori_options,
57
60
  versus: @options[:versus],
@@ -103,7 +106,7 @@ module Contrek
103
106
  matching = false
104
107
  min_x = start_x
105
108
  max_x = start_x
106
- @source_bitmap.scan(start_x: start_x, end_x: end_x) do |x, y, color|
109
+ @source_bitmap.scan(start_x: start_x, end_x: end_x, end_y: @processing_height) do |x, y, color|
107
110
  # puts "#{x} #{y}"
108
111
  if @matcher.match?(color) && matching == false
109
112
  min_x = x
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Contrek
4
- VERSION = "1.4.1"
4
+ VERSION = "1.4.2"
5
5
  end
data/lib/contrek.rb CHANGED
@@ -5,11 +5,16 @@ require "contrek/bitmaps/painting"
5
5
  require "contrek/bitmaps/rendering"
6
6
  require "contrek/bitmaps/bitmap"
7
7
  require "contrek/bitmaps/chunky_bitmap"
8
+ require "contrek/bitmaps/rgba_bitmap"
8
9
  require "contrek/bitmaps/png_bitmap"
9
10
  require "contrek/bitmaps/raw_bitmap"
10
11
  require "contrek/bitmaps/rgb_color"
11
12
  require "contrek/bitmaps/rgb_cpp_color"
12
13
  require "contrek/bitmaps/sample_generator"
14
+ require "contrek/bitmaps/streaming/raster_streamer"
15
+ require "contrek/bitmaps/streaming/sources/base"
16
+ require "contrek/bitmaps/streaming/sources/ascii"
17
+ require "contrek/bitmaps/streaming/sources/png"
13
18
  require "contrek/shared/result"
14
19
  require "contrek/finder/bounds"
15
20
  require "contrek/finder/list"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: contrek
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuele Cesaroni
@@ -99,6 +99,20 @@ dependencies:
99
99
  - - "~>"
100
100
  - !ruby/object:Gem::Version
101
101
  version: 1.3.5
102
+ - !ruby/object:Gem::Dependency
103
+ name: ffi
104
+ requirement: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '1.17'
109
+ type: :runtime
110
+ prerelease: false
111
+ version_requirements: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '1.17'
102
116
  - !ruby/object:Gem::Dependency
103
117
  name: rice
104
118
  requirement: !ruby/object:Gem::Requirement
@@ -152,6 +166,12 @@ files:
152
166
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/RemoteFastPngBitmap.h
153
167
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.c
154
168
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/spng.h
169
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/AsciiSource.cpp
170
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/AsciiSource.h
171
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/PngSource.cpp
172
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/PngSource.h
173
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/RasterSource.h
174
+ - ext/cpp_polygon_finder/PolygonFinder/src/polygon/bitmaps/streaming/RasterStreamer.h
155
175
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.cpp
156
176
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/FinderUtils.h
157
177
  - ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/List.cpp
@@ -252,7 +272,12 @@ files:
252
272
  - lib/contrek/bitmaps/rendering.rb
253
273
  - lib/contrek/bitmaps/rgb_color.rb
254
274
  - lib/contrek/bitmaps/rgb_cpp_color.rb
275
+ - lib/contrek/bitmaps/rgba_bitmap.rb
255
276
  - lib/contrek/bitmaps/sample_generator.rb
277
+ - lib/contrek/bitmaps/streaming/raster_streamer.rb
278
+ - lib/contrek/bitmaps/streaming/sources/ascii.rb
279
+ - lib/contrek/bitmaps/streaming/sources/base.rb
280
+ - lib/contrek/bitmaps/streaming/sources/png.rb
256
281
  - lib/contrek/cpp/cpp_concurrent_finder.rb
257
282
  - lib/contrek/cpp/cpp_concurrent_horizontal_merger.rb
258
283
  - lib/contrek/cpp/cpp_concurrent_merger.rb