eyes_core 3.1.1 → 3.2.1

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: a6bfdf93e062d2d12f52900e4e161d86064443a4
4
- data.tar.gz: 49420a387dc5327c6cd31a5f814e4e1e29f90948
3
+ metadata.gz: c88e7c7471138c545eb26cd0d3071f2dbf913b96
4
+ data.tar.gz: af7acdaacc4fdad1954e0c7882d4d548bf1ef4b2
5
5
  SHA512:
6
- metadata.gz: 4a3d745e90548ce9c1d9d73471a369e6c2d3eda0fa4dbabf2bfe50159180e3081248f707f15db8d3f488bf80a6a51920e3ed605ea6138b2e39cdc345e18d10f4
7
- data.tar.gz: 47fdcf476ad6fa1894e70a303b5c8793c6207688e8b9749f9058818761d3277a92ea907f129430f7ac5edbed74bcd62002753ce586caf33a4ce6b844ec45f8eb
6
+ metadata.gz: 462827e9166de30c60354313015f28172b4d7010320ebbe069a8a707634f661002658369c5d7cbf8f8383e10d77434373279c2eb98ee52e77a8037791a481c9d
7
+ data.tar.gz: b2faaa4260c1f8fbda48e70a91b4bb94b369f8eda013de55c1d1549665ebbef7ff888f53bf29b41e390cd2a5d95c8050de5d2b038edc5d2b2c9feab82b86e04a
@@ -3,26 +3,73 @@
3
3
  void Init_eyes_core() {
4
4
  VALUE Applitools = rb_define_module("Applitools");
5
5
  VALUE Resampling = rb_define_module_under(Applitools, "ResamplingFast");
6
- rb_define_method(Resampling, "interpolate_cubic", c_interpolate_cubic, 1);
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);
6
+ rb_define_method(Resampling, "resampling_first_step", c_resampling_first_step, 2);
10
7
  };
11
8
 
9
+ VALUE c_resampling_first_step(VALUE self, VALUE dst_dimension_x, VALUE dst_dimension_y) {
10
+ PIXEL *source, *destination;
11
+ unsigned long int source_width, source_height, c_dst_dimension_x, c_dst_dimension_y, w_m, h_m;
12
+ VALUE result_array;
12
13
 
13
- VALUE c_interpolate_cubic(VALUE self, VALUE data) {
14
- double t = NUM2DBL(rb_ary_entry(data, 1));
15
- VALUE p0, p1, p2, p3;
14
+ source_width = NUM2UINT(rb_funcall(self, rb_intern("width"), 0, NULL));
15
+ source_height = NUM2UINT(rb_funcall(self, rb_intern("height"), 0, NULL));
16
16
 
17
- p0 = NUM2UINT(rb_ary_entry(data, 2));
18
- p1 = NUM2UINT(rb_ary_entry(data, 3));
19
- p2 = NUM2UINT(rb_ary_entry(data, 4));
20
- p3 = NUM2UINT(rb_ary_entry(data, 5));
17
+ c_dst_dimension_x = NUM2UINT(dst_dimension_x);
18
+ c_dst_dimension_y = NUM2UINT(dst_dimension_y);
21
19
 
22
- return raw_interpolate_cubic(self, t, p0, p1, p2, p3);
20
+ w_m = source_width / c_dst_dimension_x;
21
+ h_m = source_height / c_dst_dimension_y;
22
+
23
+ if (w_m == 0) {
24
+ w_m = 1;
25
+ };
26
+
27
+ if (h_m == 0) {
28
+ h_m = 1;
29
+ };
30
+
31
+ source = get_c_array(self);
32
+
33
+ destination = get_bicubic_points(source, source_width, source_height, c_dst_dimension_x * w_m, c_dst_dimension_y * h_m);
34
+
35
+ if (w_m * h_m > 1) {
36
+ source = destination;
37
+ destination = c_scale_points(source, c_dst_dimension_x, c_dst_dimension_y, w_m, h_m);
38
+ }
39
+
40
+ result_array = get_ruby_array(self, destination, c_dst_dimension_x * c_dst_dimension_y);
41
+ free(destination);
42
+ return result_array;
23
43
  };
24
44
 
25
- VALUE raw_interpolate_cubic(VALUE self, double t, VALUE p0, VALUE p1, VALUE p2, VALUE p3) {
45
+ VALUE get_ruby_array(VALUE self, PIXEL *pixels, unsigned long int pixels_size) {
46
+ VALUE result_array;
47
+ unsigned long int i;
48
+ result_array = rb_ary_new2(pixels_size);
49
+ for (i=0; i<pixels_size; i++) {
50
+ rb_ary_store(result_array, i, UINT2NUM(pixels[i]));
51
+ };
52
+ return result_array;
53
+ }
54
+
55
+ PIXEL* get_c_array(VALUE self) {
56
+ unsigned long int w,h,i;
57
+ PIXEL* ary;
58
+ VALUE pixels;
59
+
60
+ pixels = rb_funcall(self, rb_intern("pixels"), 0, NULL);
61
+ w = NUM2UINT(rb_funcall(self, rb_intern("width"), 0, NULL));
62
+ h = NUM2UINT(rb_funcall(self, rb_intern("height"), 0, NULL));
63
+ ary = (PIXEL*)malloc( w*h*sizeof(PIXEL));
64
+
65
+ for(i=0; i<w*h; i++) {
66
+ ary[i] = NUM2UINT(rb_ary_entry(pixels, i));
67
+ }
68
+
69
+ return ary;
70
+ }
71
+
72
+ PIXEL raw_interpolate_cubic(double t, PIXEL p0, PIXEL p1, PIXEL p2, PIXEL p3) {
26
73
  BYTE new_r, new_g, new_b, new_a;
27
74
 
28
75
  new_r = interpolate_char(t, R_BYTE(p0), R_BYTE(p1), R_BYTE(p2), R_BYTE(p3));
@@ -30,7 +77,7 @@ VALUE raw_interpolate_cubic(VALUE self, double t, VALUE p0, VALUE p1, VALUE p2,
30
77
  new_b = interpolate_char(t, B_BYTE(p0), B_BYTE(p1), B_BYTE(p2), B_BYTE(p3));
31
78
  new_a = interpolate_char(t, A_BYTE(p0), A_BYTE(p1), A_BYTE(p2), A_BYTE(p3));
32
79
 
33
- return UINT2NUM(BUILD_PIXEL(new_r, new_g, new_b, new_a));
80
+ return BUILD_PIXEL(new_r, new_g, new_b, new_a);
34
81
  }
35
82
 
36
83
  BYTE interpolate_char(double t, BYTE c0, BYTE c1, BYTE c2, BYTE c3) {
@@ -48,45 +95,7 @@ BYTE interpolate_char(double t, BYTE c0, BYTE c1, BYTE c2, BYTE c3) {
48
95
  return (BYTE)(res);
49
96
  };
50
97
 
51
- VALUE c_merge_pixels(VALUE self, VALUE pixels) {
52
- unsigned int i, size, real_colors, acum_r, acum_g, acum_b, acum_a;
53
- BYTE new_r, new_g, new_b, new_a;
54
- PIXEL pix;
55
-
56
- acum_r = 0;
57
- acum_g = 0;
58
- acum_b = 0;
59
- acum_a = 0;
60
-
61
- new_r = 0;
62
- new_g = 0;
63
- new_b = 0;
64
- new_a = 0;
65
-
66
- size = NUM2UINT(rb_funcall(pixels, rb_intern("size"), 0, Qnil)) - 1;
67
- real_colors = 0;
68
-
69
- for(i=1; i < size; i++) {
70
- pix = NUM2UINT(rb_ary_entry(pixels, i));
71
- if(A_BYTE(pix) != 0) {
72
- acum_r += R_BYTE(pix);
73
- acum_g += G_BYTE(pix);
74
- acum_b += B_BYTE(pix);
75
- acum_a += A_BYTE(pix);
76
- real_colors += 1;
77
- }
78
- }
79
-
80
- if(real_colors > 0) {
81
- new_r = (BYTE)(acum_r/real_colors + 0.5);
82
- new_g = (BYTE)(acum_g/real_colors + 0.5);
83
- new_b = (BYTE)(acum_b/real_colors + 0.5);
84
- }
85
- new_a = (BYTE)(acum_a/(size - 1) + 0.5);
86
- return UINT2NUM(BUILD_PIXEL(new_r, new_g, new_b, new_a));
87
- }
88
-
89
- VALUE raw_merge_pixels(VALUE merge_pixels[], unsigned int size) {
98
+ PIXEL raw_merge_pixels(PIXEL* merge_pixels, unsigned int size) {
90
99
  unsigned int i, real_colors, acum_r, acum_g, acum_b, acum_a;
91
100
  BYTE new_r, new_g, new_b, new_a;
92
101
  PIXEL pix;
@@ -104,103 +113,140 @@ VALUE raw_merge_pixels(VALUE merge_pixels[], unsigned int size) {
104
113
  real_colors = 0;
105
114
 
106
115
  for(i=0; i < size; i++) {
107
- pix = NUM2UINT(merge_pixels[i]);
116
+ pix = merge_pixels[i];
108
117
  if(A_BYTE(pix) != 0) {
109
118
  acum_r += R_BYTE(pix);
110
119
  acum_g += G_BYTE(pix);
111
120
  acum_b += B_BYTE(pix);
112
121
  acum_a += A_BYTE(pix);
113
122
  real_colors += 1;
114
- }
115
- }
123
+ };
124
+ };
116
125
 
117
126
  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, i, y, x;
128
- double step;
129
- VALUE result_array;
127
+ new_r = (BYTE)(acum_r/real_colors);
128
+ new_g = (BYTE)(acum_g/real_colors);
129
+ new_b = (BYTE)(acum_b/real_colors);
130
+ };
131
+ new_a = (BYTE)(acum_a/size);
132
+ return BUILD_PIXEL(new_r, new_g, new_b, new_a);
133
+ };
130
134
 
131
- unsigned long steps [NUM2UINT(dst_dimension)];
132
- double residues [NUM2UINT(dst_dimension)];
133
- VALUE line_bounds;
135
+ void setup_steps_residues(unsigned long int *steps, double *residues,
136
+ unsigned long int src_dimension, unsigned long int dst_dimension) {
137
+ unsigned long int i;
138
+ double step = (double) (src_dimension - 1) / (dst_dimension - 1);
139
+ for(i = 0; i < dst_dimension - 1; i++) {
140
+ steps[i] = (unsigned long int) i*step;
141
+ residues[i] = i*step - steps[i];
142
+ };
134
143
 
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;
144
+ steps[dst_dimension - 1] = src_dimension - 2;
145
+ residues[dst_dimension - 1] = 1;
146
+ };
139
147
 
140
- if (RTEST(direction)) {
141
- y_bounds = NUM2UINT(rb_funcall(self, rb_intern("width"), 0, NULL));
148
+ PIXEL get_line_pixel(PIXEL* source, unsigned long int line, long int pixel,
149
+ unsigned long int src_dimension_x) {
150
+ if(pixel >= 0 && pixel < (long int)src_dimension_x) {
151
+ return source[line * src_dimension_x + pixel];
142
152
  } else {
143
- y_bounds = NUM2UINT(rb_funcall(self, rb_intern("height"), 0, NULL));
153
+ return 0;
144
154
  };
155
+ };
145
156
 
146
- pixels_size = y_bounds * c_dst_dimension;
147
- result_array = rb_ary_new2(pixels_size);
157
+ PIXEL get_column_pixel(PIXEL* source,
158
+ unsigned long int column, long int pixel,
159
+ unsigned long int src_dimension_y, unsigned long int src_dimension_x) {
148
160
 
149
- for (i = 0; i < c_dst_dimension; i++) {
150
- steps[i] = (unsigned long)i*step;
151
- residues[i] = i*step - steps[i];
161
+ if(pixel >=0 && pixel < (long int)src_dimension_y) {
162
+ return source[src_dimension_x * pixel + column];
163
+ } else {
164
+ return 0;
152
165
  };
166
+ };
153
167
 
154
- for (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 (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)))
168
+ PIXEL* get_bicubic_points(PIXEL* source_array,
169
+ unsigned long int src_dimension_x, unsigned long int src_dimension_y,
170
+ unsigned long int dst_dimension_x, unsigned long int dst_dimension_y) {
171
+ PIXEL* dest, *source;
172
+ unsigned long int index_y, index, y, x;
173
+ unsigned long int* steps;
174
+ double* residues;
175
+
176
+ steps = (unsigned long int*) malloc(dst_dimension_x * sizeof(unsigned long int));
177
+ residues = (double*) malloc(dst_dimension_x * sizeof(double));
178
+ setup_steps_residues(steps, residues, src_dimension_x, dst_dimension_x);
179
+
180
+ source = source_array;
181
+ dest = (PIXEL*)malloc( src_dimension_y*dst_dimension_x*sizeof(PIXEL) );
182
+
183
+ for (y=0; y < src_dimension_y; y++) {
184
+ index_y = dst_dimension_x * y;
185
+ for (x=0; x < dst_dimension_x; x++) {
186
+ index = index_y + x;
187
+ dest[index] = raw_interpolate_cubic(residues[x],
188
+ get_line_pixel(source, y, steps[x] - 1, src_dimension_x),
189
+ get_line_pixel(source, y, steps[x], src_dimension_x),
190
+ get_line_pixel(source, y, steps[x] + 1, src_dimension_x),
191
+ get_line_pixel(source, y, steps[x] + 2, src_dimension_x)
169
192
  );
170
- }
171
- }
193
+ };
194
+ };
172
195
 
173
- return result_array;
174
- }
196
+ steps = realloc(steps, dst_dimension_y * sizeof(unsigned long int));
197
+ residues = realloc(residues, dst_dimension_y * sizeof(double));
198
+ setup_steps_residues(steps, residues, src_dimension_y, dst_dimension_y);
199
+
200
+ free(source);
201
+ source = dest;
202
+ dest = (PIXEL*)malloc( dst_dimension_x * dst_dimension_y * sizeof(PIXEL));
203
+
204
+ for (y=0; y < dst_dimension_x; y++) {
205
+ for (x=0; x < dst_dimension_y; x++) {
206
+ index = dst_dimension_x * x + y;
207
+ dest[index] = raw_interpolate_cubic(residues[x],
208
+ get_column_pixel(source, y, steps[x] - 1, src_dimension_y, dst_dimension_x),
209
+ get_column_pixel(source, y, steps[x], src_dimension_y, dst_dimension_x),
210
+ get_column_pixel(source, y, steps[x] + 1, src_dimension_y, dst_dimension_x),
211
+ get_column_pixel(source, y, steps[x] + 2, src_dimension_y, dst_dimension_x)
212
+ );
213
+ };
214
+ };
215
+
216
+ free(source);
217
+ free(steps);
218
+ free(residues);
219
+
220
+ return dest;
221
+ };
175
222
 
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, i, j;
178
- unsigned int c_w_m, c_h_m, buffer_index, buffer_size, x, y;
179
- VALUE pixels_to_merge [NUM2UINT(w_m) * NUM2UINT(h_m)];
180
- VALUE result;
223
+ PIXEL* c_scale_points(PIXEL* source, unsigned long int dst_width, unsigned long int dst_height,
224
+ unsigned long int w_m, unsigned long int h_m) {
181
225
 
182
- c_dst_height = NUM2UINT(dst_height);
183
- c_dst_width = NUM2UINT(dst_width);
226
+ unsigned long int y_pos, x_pos, index, i, j, x, y, buffer_size, buffer_index;
227
+ PIXEL* pixels_to_merge;
228
+ PIXEL* result;
184
229
 
185
- c_w_m = NUM2UINT(w_m);
186
- c_h_m = NUM2UINT(h_m);
230
+ pixels_to_merge = malloc(w_m*h_m*sizeof(PIXEL));
231
+ result = malloc(dst_width * dst_height * sizeof(PIXEL));
187
232
 
188
- result = rb_ary_new2(c_dst_width * c_dst_height);
189
- buffer_size = c_h_m * c_w_m;
233
+ buffer_size = h_m * w_m;
190
234
 
191
- for (i = 0; i < c_dst_height; i++) {
192
- for (j = 0; j < c_dst_width; j++) {
235
+ for (i = 0; i < dst_height; i++) {
236
+ for (j = 0; j < dst_width; j++) {
193
237
  buffer_index = 0;
194
- for (y = 0; y < c_h_m; y++) {
195
- y_pos = i * c_h_m + y;
196
- for (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
- }
238
+ for (y = 0; y < h_m; y++) {
239
+ y_pos = i * h_m + y;
240
+ for (x = 0; x < w_m; x++) {
241
+ x_pos = j * w_m + x;
242
+ pixels_to_merge[buffer_index++] = source[dst_width * w_m * y_pos + x_pos];
243
+ };
244
+ };
245
+ index = i * dst_width + j;
246
+ result[index] = raw_merge_pixels(pixels_to_merge, buffer_size);
247
+
248
+ };
249
+ };
250
+ free(source);
205
251
  return result;
206
- }
252
+ };
@@ -17,12 +17,17 @@ typedef unsigned char BYTE; // Bytes use 8 bits unsigned integers
17
17
 
18
18
  void Init_resampling();
19
19
 
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);
23
- VALUE c_merge_pixels(VALUE, VALUE);
24
- VALUE raw_merge_pixels(VALUE[], unsigned int);
25
- VALUE c_bicubic_points(VALUE, VALUE, VALUE, VALUE);
20
+
26
21
  BYTE interpolate_char(double, BYTE, BYTE, BYTE, BYTE);
27
22
 
23
+ PIXEL* get_bicubic_points(PIXEL*, unsigned long int, unsigned long int, unsigned long int, unsigned long int);
24
+
25
+ PIXEL* get_c_array(VALUE);
26
+ VALUE c_resampling_first_step(VALUE, VALUE, VALUE);
27
+ VALUE get_ruby_array(VALUE, PIXEL*, unsigned long int);
28
+ PIXEL get_line_pixel(PIXEL*, unsigned long int, long int, unsigned long int);
29
+ PIXEL get_column_pixel(PIXEL*, unsigned long int, long int, unsigned long int, unsigned long int);
30
+ PIXEL raw_merge_pixels(PIXEL*, unsigned int);
31
+ PIXEL* c_scale_points(PIXEL*, unsigned long int, unsigned long int, unsigned long int, unsigned long int);
32
+
28
33
  #endif
@@ -13,22 +13,9 @@ end
13
13
  module Applitools::ChunkyPNG
14
14
  module Resampling
15
15
  def resample_bicubic!(dst_width, dst_height)
16
- w_m = [1, width / dst_width].max
17
- h_m = [1, height / dst_height].max
18
-
19
- dst_width2 = dst_width * w_m
20
- dst_height2 = dst_height * h_m
21
-
22
- pixels = bicubic_x_points(dst_width2)
23
- replace_canvas!(dst_width2, height, pixels)
24
-
25
- pixels = bicubic_y_points(dst_height2)
26
- replace_canvas!(dst_width2, dst_height2, pixels)
27
-
28
- return self unless w_m * h_m > 1
29
-
30
- pixels = scale_points2(dst_width, dst_height, w_m, h_m)
31
- replace_canvas!(dst_width, dst_height, pixels)
16
+ new_pixels = resampling_first_step(dst_width, dst_height)
17
+ replace_canvas!(dst_width, dst_height, new_pixels)
18
+ self
32
19
  end
33
20
 
34
21
  def resample_bicubic(new_width, new_height)
@@ -1,3 +1,3 @@
1
1
  module Applitools
2
- VERSION = '3.1.1'.freeze
2
+ VERSION = '3.2.1'.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.1.1
4
+ version: 3.2.1
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-04-05 00:00:00.000000000 Z
11
+ date: 2017-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oily_png