eyes_core 3.0.7 → 3.0.8

Sign up to get free protection for your applications and to get access to all the features.
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