eyes_core 3.1.1 → 3.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/eyes_core/eyes_core.c +173 -127
- data/ext/eyes_core/eyes_core.h +11 -6
- data/lib/applitools/chunky_png/resampling.rb +3 -16
- data/lib/applitools/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c88e7c7471138c545eb26cd0d3071f2dbf913b96
|
4
|
+
data.tar.gz: af7acdaacc4fdad1954e0c7882d4d548bf1ef4b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 462827e9166de30c60354313015f28172b4d7010320ebbe069a8a707634f661002658369c5d7cbf8f8383e10d77434373279c2eb98ee52e77a8037791a481c9d
|
7
|
+
data.tar.gz: b2faaa4260c1f8fbda48e70a91b4bb94b369f8eda013de55c1d1549665ebbef7ff888f53bf29b41e390cd2a5d95c8050de5d2b038edc5d2b2c9feab82b86e04a
|
data/ext/eyes_core/eyes_core.c
CHANGED
@@ -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, "
|
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
|
-
|
14
|
-
|
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
|
-
|
18
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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 =
|
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
|
119
|
-
new_g = (BYTE)(acum_g/real_colors
|
120
|
-
new_b = (BYTE)(acum_b/real_colors
|
121
|
-
}
|
122
|
-
new_a = (BYTE)(acum_a/
|
123
|
-
return
|
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
|
-
|
132
|
-
|
133
|
-
|
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
|
-
|
136
|
-
|
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
|
-
|
141
|
-
|
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
|
-
|
153
|
+
return 0;
|
144
154
|
};
|
155
|
+
};
|
145
156
|
|
146
|
-
|
147
|
-
|
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
|
-
|
150
|
-
|
151
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
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
|
-
|
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
|
-
|
177
|
-
unsigned long
|
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
|
-
|
183
|
-
|
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
|
-
|
186
|
-
|
230
|
+
pixels_to_merge = malloc(w_m*h_m*sizeof(PIXEL));
|
231
|
+
result = malloc(dst_width * dst_height * sizeof(PIXEL));
|
187
232
|
|
188
|
-
|
189
|
-
buffer_size = c_h_m * c_w_m;
|
233
|
+
buffer_size = h_m * w_m;
|
190
234
|
|
191
|
-
for (i = 0; i <
|
192
|
-
for (j = 0; 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 <
|
195
|
-
y_pos = i *
|
196
|
-
for (x = 0; x <
|
197
|
-
x_pos = j *
|
198
|
-
pixels_to_merge[buffer_index++] =
|
199
|
-
}
|
200
|
-
}
|
201
|
-
index = i *
|
202
|
-
|
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
|
+
};
|
data/ext/eyes_core/eyes_core.h
CHANGED
@@ -17,12 +17,17 @@ typedef unsigned char BYTE; // Bytes use 8 bits unsigned integers
|
|
17
17
|
|
18
18
|
void Init_resampling();
|
19
19
|
|
20
|
-
|
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
|
-
|
17
|
-
|
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)
|
data/lib/applitools/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2017-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oily_png
|