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 +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
|