eyes_core 3.0.7 → 3.0.8

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
  SHA1:
3
- metadata.gz: 38515d04836152a9f34789c311d48d02d9d6521d
4
- data.tar.gz: 4e28df8c66469f4cdef6654b3ae564eaa3ecbf13
3
+ metadata.gz: 734dda49eb71281c85770bc8e075346b303417f8
4
+ data.tar.gz: '08dfc01e914c3c9d42958d018dba34a8a3305060'
5
5
  SHA512:
6
- metadata.gz: 0daa88afc091c11823b9d217497e9a2b786749cc47fb30be654ee0a76de70a5624418cef6e2b62c6ddd80b36c3d395154328829200b8b7be5a2b9f1f7092758f
7
- data.tar.gz: 8694cf67a6d57a16d68571c42c767c372758cf4145875629609238f2ac9cf6b06a97ca30f3280ede2f19ec5e8362b802433d55ba1a06dbf77ccbfb372282eacb
6
+ metadata.gz: 3365239f1bf1f1843936585a9c25bc7c2804d5ee72ff3928e32e242d0cff34447af492545298a1c13f0e819668016eb4ea5730cec7b6dd1a5f46575e8c6c9195
7
+ data.tar.gz: 5292266eaf979ff3caad6b05cb937fa64e9eb25f0e67378625f26ca4450da4460563615c5601564468ddfff0c5767f98602b6dd827293bc418448e0bfa8de1e5
@@ -5,12 +5,13 @@ void Init_eyes_core() {
5
5
  VALUE Resampling = rb_define_module_under(Applitools, "ResamplingFast");
6
6
  rb_define_method(Resampling, "interpolate_cubic", c_interpolate_cubic, 1);
7
7
  rb_define_method(Resampling, "merge_pixels", c_merge_pixels, 1);
8
+ rb_define_method(Resampling, "bicubic_points2", c_bicubic_points, 3);
9
+ rb_define_method(Resampling, "scale_points2", scale_points2, 4);
8
10
  };
9
11
 
10
12
 
11
13
  VALUE c_interpolate_cubic(VALUE self, VALUE data) {
12
14
  double t = NUM2DBL(rb_ary_entry(data, 1));
13
- BYTE new_r, new_g, new_b, new_a;
14
15
  VALUE p0, p1, p2, p3;
15
16
 
16
17
  p0 = NUM2UINT(rb_ary_entry(data, 2));
@@ -18,13 +19,19 @@ VALUE c_interpolate_cubic(VALUE self, VALUE data) {
18
19
  p2 = NUM2UINT(rb_ary_entry(data, 4));
19
20
  p3 = NUM2UINT(rb_ary_entry(data, 5));
20
21
 
22
+ return raw_interpolate_cubic(self, t, p0, p1, p2, p3);
23
+ };
24
+
25
+ VALUE raw_interpolate_cubic(VALUE self, double t, VALUE p0, VALUE p1, VALUE p2, VALUE p3) {
26
+ BYTE new_r, new_g, new_b, new_a;
27
+
21
28
  new_r = interpolate_char(t, R_BYTE(p0), R_BYTE(p1), R_BYTE(p2), R_BYTE(p3));
22
29
  new_g = interpolate_char(t, G_BYTE(p0), G_BYTE(p1), G_BYTE(p2), G_BYTE(p3));
23
30
  new_b = interpolate_char(t, B_BYTE(p0), B_BYTE(p1), B_BYTE(p2), B_BYTE(p3));
24
31
  new_a = interpolate_char(t, A_BYTE(p0), A_BYTE(p1), A_BYTE(p2), A_BYTE(p3));
25
32
 
26
33
  return UINT2NUM(BUILD_PIXEL(new_r, new_g, new_b, new_a));
27
- };
34
+ }
28
35
 
29
36
  BYTE interpolate_char(double t, BYTE c0, BYTE c1, BYTE c2, BYTE c3) {
30
37
  double a, b, c, d, res;
@@ -78,3 +85,122 @@ VALUE c_merge_pixels(VALUE self, VALUE pixels) {
78
85
  new_a = (BYTE)(acum_a/(size - 1) + 0.5);
79
86
  return UINT2NUM(BUILD_PIXEL(new_r, new_g, new_b, new_a));
80
87
  }
88
+
89
+ VALUE raw_merge_pixels(VALUE merge_pixels[], unsigned int size) {
90
+ unsigned int i, real_colors, acum_r, acum_g, acum_b, acum_a;
91
+ BYTE new_r, new_g, new_b, new_a;
92
+ PIXEL pix;
93
+
94
+ acum_r = 0;
95
+ acum_g = 0;
96
+ acum_b = 0;
97
+ acum_a = 0;
98
+
99
+ new_r = 0;
100
+ new_g = 0;
101
+ new_b = 0;
102
+ new_a = 0;
103
+
104
+ real_colors = 0;
105
+
106
+ for(i=0; i < size; i++) {
107
+ pix = NUM2UINT(merge_pixels[i]);
108
+ if(A_BYTE(pix) != 0) {
109
+ acum_r += R_BYTE(pix);
110
+ acum_g += G_BYTE(pix);
111
+ acum_b += B_BYTE(pix);
112
+ acum_a += A_BYTE(pix);
113
+ real_colors += 1;
114
+ }
115
+ }
116
+
117
+ if(real_colors > 0) {
118
+ new_r = (BYTE)(acum_r/real_colors + 0.5);
119
+ new_g = (BYTE)(acum_g/real_colors + 0.5);
120
+ new_b = (BYTE)(acum_b/real_colors + 0.5);
121
+ }
122
+ new_a = (BYTE)(acum_a/(size - 1) + 0.5);
123
+ return UINT2NUM(BUILD_PIXEL(new_r, new_g, new_b, new_a));
124
+ }
125
+
126
+ VALUE c_bicubic_points(VALUE self, VALUE src_dimension, VALUE dst_dimension, VALUE direction) {
127
+ unsigned long y_bounds, pixels_size, c_src_dimension, c_dst_dimension, index, index_y;
128
+ double step;
129
+ VALUE result_array;
130
+
131
+ unsigned long steps [NUM2UINT(dst_dimension)];
132
+ double residues [NUM2UINT(dst_dimension)];
133
+ VALUE line_bounds;
134
+
135
+ c_src_dimension = NUM2UINT(src_dimension);
136
+ c_dst_dimension = NUM2UINT(dst_dimension);
137
+
138
+ step = (double)(c_src_dimension - 1) / c_dst_dimension;
139
+
140
+ if (RTEST(direction)) {
141
+ y_bounds = NUM2UINT(rb_funcall(self, rb_intern("width"), 0, NULL));
142
+ } else {
143
+ y_bounds = NUM2UINT(rb_funcall(self, rb_intern("height"), 0, NULL));
144
+ };
145
+
146
+ pixels_size = y_bounds * c_dst_dimension;
147
+ result_array = rb_ary_new2(pixels_size);
148
+
149
+ for (unsigned long i=0; i < c_dst_dimension; i++) {
150
+ steps[i] = (unsigned long)i*step;
151
+ residues[i] = i*step - steps[i];
152
+ };
153
+
154
+ for (unsigned long y=0; y < y_bounds; y++) {
155
+ line_bounds = rb_funcall(self, rb_intern("line_with_bounds"), 3, UINT2NUM(y), src_dimension, direction);
156
+
157
+ index_y = c_dst_dimension * y;
158
+ for (unsigned long x=0; x < c_dst_dimension; x++) {
159
+ if (RTEST(direction)) {
160
+ index = y_bounds * x + y;
161
+ } else {
162
+ index = index_y + x;
163
+ }
164
+ rb_ary_store(result_array, index, raw_interpolate_cubic(self, residues[x],
165
+ NUM2UINT(rb_ary_entry(line_bounds, steps[x])),
166
+ NUM2UINT(rb_ary_entry(line_bounds, steps[x] + 1)),
167
+ NUM2UINT(rb_ary_entry(line_bounds, steps[x] + 2)),
168
+ NUM2UINT(rb_ary_entry(line_bounds, steps[x] + 3)))
169
+ );
170
+ }
171
+ }
172
+
173
+ return result_array;
174
+ }
175
+
176
+ VALUE scale_points2(VALUE self, VALUE dst_width, VALUE dst_height, VALUE w_m, VALUE h_m) {
177
+ unsigned long c_dst_height, c_dst_width, y_pos, x_pos, index;
178
+ unsigned int c_w_m, c_h_m, buffer_index, buffer_size;
179
+ VALUE pixels_to_merge [NUM2UINT(w_m) * NUM2UINT(h_m)];
180
+ VALUE result;
181
+
182
+ c_dst_height = NUM2UINT(dst_height);
183
+ c_dst_width = NUM2UINT(dst_width);
184
+
185
+ c_w_m = NUM2UINT(w_m);
186
+ c_h_m = NUM2UINT(h_m);
187
+
188
+ result = rb_ary_new2(c_dst_width * c_dst_height);
189
+ buffer_size = c_h_m * c_w_m;
190
+
191
+ for (unsigned long i = 0; i < c_dst_height; i++) {
192
+ for (unsigned long j = 0; j < c_dst_width; j++) {
193
+ buffer_index = 0;
194
+ for (unsigned int y = 0; y < c_h_m; y++) {
195
+ y_pos = i * c_h_m + y;
196
+ for (unsigned int x = 0; x < c_w_m; x++) {
197
+ x_pos = j * c_w_m + x;
198
+ pixels_to_merge[buffer_index++] = rb_funcall(self, rb_intern("get_pixel"), 2, UINT2NUM(x_pos), UINT2NUM(y_pos));
199
+ }
200
+ }
201
+ index = i * c_dst_width + j;
202
+ rb_ary_store(result, index, raw_merge_pixels(pixels_to_merge, buffer_size));
203
+ }
204
+ }
205
+ return result;
206
+ }
@@ -18,7 +18,11 @@ typedef unsigned char BYTE; // Bytes use 8 bits unsigned integers
18
18
  void Init_resampling();
19
19
 
20
20
  VALUE c_interpolate_cubic(VALUE,VALUE);
21
+ VALUE raw_interpolate_cubic(VALUE, double, VALUE, VALUE, VALUE, VALUE);
22
+ VALUE scale_points2(VALUE, VALUE, VALUE, VALUE, VALUE);
21
23
  VALUE c_merge_pixels(VALUE, VALUE);
24
+ VALUE raw_merge_pixels(VALUE[], unsigned int);
25
+ VALUE c_bicubic_points(VALUE, VALUE, VALUE, VALUE);
22
26
  BYTE interpolate_char(double, BYTE, BYTE, BYTE, BYTE);
23
27
 
24
28
  #endif
@@ -7,31 +7,15 @@ module Applitools::ChunkyPNG
7
7
  dst_width2 = dst_width * w_m
8
8
  dst_height2 = dst_height * h_m
9
9
 
10
- points = bicubic_x_points(dst_width2)
11
- pixels = Array.new(points.size)
12
-
13
- points.each do |interpolation_data|
14
- pixels[interpolation_data[0]] = interpolate_cubic(interpolation_data)
15
- end
10
+ pixels = bicubic_x_points(dst_width2)
16
11
  replace_canvas!(dst_width2, height, pixels)
17
12
 
18
- points = bicubic_y_points(dst_height2)
19
- pixels = Array.new(points.size)
20
-
21
- points.each do |interpolation_data|
22
- pixels[interpolation_data[0]] = interpolate_cubic(interpolation_data)
23
- end
13
+ pixels = bicubic_y_points(dst_height2)
24
14
  replace_canvas!(dst_width2, dst_height2, pixels)
25
15
 
26
16
  return self unless w_m * h_m > 1
27
17
 
28
- points = scale_points(dst_width, dst_height, w_m, h_m)
29
- pixels = Array.new(points.size)
30
-
31
- points.each do |merge_data|
32
- pixels[merge_data[0]] = merge_pixels(merge_data)
33
- end
34
-
18
+ pixels = scale_points2(dst_width, dst_height, w_m, h_m);
35
19
  replace_canvas!(dst_width, dst_height, pixels)
36
20
  end
37
21
 
@@ -40,101 +24,19 @@ module Applitools::ChunkyPNG
40
24
  end
41
25
 
42
26
  def bicubic_x_points(dst_width)
43
- bicubic_points(width, dst_width, false)
27
+ bicubic_points2(width, dst_width, false)
44
28
  end
45
29
 
46
30
  def bicubic_y_points(dst_height)
47
- bicubic_points(height, dst_height, true)
48
- end
49
-
50
- def bicubic_points(src_dimension, dst_dimension, direction, y_start_position = 0)
51
- step = (src_dimension - 1).to_f / dst_dimension
52
- y_bounds = direction ? width : height
53
- raise ArgumentError.new 'Start position value is invalid!' unless y_start_position < y_bounds
54
- pixels_size = (y_bounds - y_start_position) * dst_dimension
55
-
56
- steps = Array.new(dst_dimension)
57
- residues = Array.new(dst_dimension)
58
-
59
- (0..dst_dimension - 1).each do |i|
60
- steps[i] = (i * step).to_i
61
- residues[i] = i * step - steps[i]
62
- end
63
- Enumerator.new(pixels_size) do |enum|
64
- (y_start_position..y_bounds - 1).each do |y|
65
- line = (direction ? column(y) : row(y))
66
-
67
- line_with_bounds = [imaginable_point(line[0], line[1])] + line + [
68
- imaginable_point(line[src_dimension - 2], line[src_dimension - 3]),
69
- imaginable_point(line[src_dimension - 1], line[src_dimension - 2])
70
- ]
71
-
72
- index_y = dst_dimension * y
73
- (0..dst_dimension - 1).each do |x|
74
- index = direction ? y_bounds * x + y : index_y + x
75
- enum << ([index, residues[x]] + line_with_bounds.last(src_dimension + 3 - steps[x]).first(4))
76
- end
77
- end
78
- end
31
+ bicubic_points2(height, dst_height, true)
79
32
  end
80
33
 
81
- def scale_points(dst_width, dst_height, w_m, h_m)
82
- Enumerator.new(dst_width * dst_height) do |enum|
83
- (0..dst_height - 1).each do |i|
84
- (0..dst_width - 1).each do |j|
85
- pixels_to_merge = []
86
- (0..h_m - 1).each do |y|
87
- y_pos = i * h_m + y
88
- (0..w_m - 1).each do |x|
89
- x_pos = j * w_m + x
90
- pixels_to_merge << get_pixel(x_pos, y_pos)
91
- end
92
- end
93
- index = i * dst_width + j
94
- enum << ([index] + pixels_to_merge)
95
- end
96
- end
97
- end
98
- end
99
-
100
- def merge_pixels(merge_data)
101
- pixels = merge_data[1..merge_data.size]
102
- merged_data = pixels.each_with_object(r: 0, g: 0, b: 0, a: 0, real_colors: 0) do |pixel, result|
103
- unless ChunkyPNG::Color.fully_transparent?(pixel)
104
- result[:real_colors] += 1
105
- [:r, :g, :b].each do |ch|
106
- result[ch] += ChunkyPNG::Color.send(ch, pixel)
107
- end
108
- end
109
- result[:a] += ChunkyPNG::Color.a(pixel)
110
- result
111
- end
112
-
113
- r = merged_data[:real_colors] > 0 ? merged_data[:r] / merged_data[:real_colors] : 0
114
- g = merged_data[:real_colors] > 0 ? merged_data[:g] / merged_data[:real_colors] : 0
115
- b = merged_data[:real_colors] > 0 ? merged_data[:b] / merged_data[:real_colors] : 0
116
- a = merged_data[:a] / pixels.size
117
-
118
- ChunkyPNG::Color.rgba(r, g, b, a)
119
- end
120
-
121
- def interpolate_cubic(data)
122
- result = {}
123
- t = data[1]
124
- [:r, :g, :b, :a].each do |chan|
125
- c0 = ChunkyPNG::Color.send(chan, data[2])
126
- c1 = ChunkyPNG::Color.send(chan, data[3])
127
- c2 = ChunkyPNG::Color.send(chan, data[4])
128
- c3 = ChunkyPNG::Color.send(chan, data[5])
129
-
130
- a = -0.5 * c0 + 1.5 * c1 - 1.5 * c2 + 0.5 * c3
131
- b = c0 - 2.5 * c1 + 2 * c2 - 0.5 * c3
132
- c = 0.5 * c2 - 0.5 * c0
133
- d = c1
134
-
135
- result[chan] = [0, [255, (a * t**3 + b * t**2 + c * t + d).to_i].min].max
136
- end
137
- ChunkyPNG::Color.rgba(result[:r], result[:g], result[:b], result[:a])
34
+ def line_with_bounds(y, src_dimension, direction)
35
+ line = (direction ? column(y) : row(y))
36
+ [imaginable_point(line[0], line[1])] + line + [
37
+ imaginable_point(line[src_dimension - 2], line[src_dimension - 3]),
38
+ imaginable_point(line[src_dimension - 1], line[src_dimension - 2])
39
+ ]
138
40
  end
139
41
 
140
42
  def imaginable_point(point1, point2)
@@ -13,6 +13,13 @@ module Applitools
13
13
  @datastream = ::ChunkyPNG::Datastream.from_string image
14
14
  end
15
15
 
16
+ def update!(image)
17
+ Applitools::ArgumentGuard.not_nil(image, 'image')
18
+ Applitools::ArgumentGuard.is_a?(image, 'image', ::ChunkyPNG::Image)
19
+ @datastream = image.to_datastream
20
+ self
21
+ end
22
+
16
23
  def to_blob
17
24
  @datastream.to_blob
18
25
  end
@@ -21,6 +28,8 @@ module Applitools
21
28
  restore
22
29
  end
23
30
 
31
+ alias image __getobj__
32
+
24
33
  def header
25
34
  @datastream.header_chunk
26
35
  end
@@ -84,7 +84,9 @@ module Applitools::Utils
84
84
  image_ratio = image.width.to_f / image.height.to_f
85
85
  scale_width = (image.width * scale_ratio).ceil
86
86
  scale_height = (scale_width / image_ratio).ceil
87
- resize_image!(image, scale_width, scale_height)
87
+ buffered_image = image.image
88
+ resize_image!(buffered_image, scale_width, scale_height)
89
+ image.update!(buffered_image)
88
90
  end
89
91
 
90
92
  def scale(image, scale_ratio)
@@ -95,7 +97,7 @@ module Applitools::Utils
95
97
  Applitools::ArgumentGuard.not_nil(new_width, 'new_width')
96
98
  Applitools::ArgumentGuard.not_nil(new_height, 'new_height')
97
99
  Applitools::ArgumentGuard.not_nil(image, 'image')
98
- Applitools::ArgumentGuard.is_a?(image, 'image', Applitools::Screenshot)
100
+ Applitools::ArgumentGuard.is_a?(image, 'image', ::ChunkyPNG::Image)
99
101
 
100
102
  raise Applitools::EyesIllegalArgument.new "Invalid width: #{new_width}" if new_width <= 0
101
103
  raise Applitools::EyesIllegalArgument.new "Invalid height: #{new_height}" if new_height <= 0
@@ -1,3 +1,3 @@
1
1
  module Applitools
2
- VERSION = '3.0.7'.freeze
2
+ VERSION = '3.0.8'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eyes_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.7
4
+ version: 3.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Applitools Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-23 00:00:00.000000000 Z
11
+ date: 2017-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oily_png